This rule is part of MISRA C++:2023.
Usage of this content is governed by Sonar’s terms and conditions. Redistribution is
prohibited.
Rule 7.11.2 - An array passed as a function argument shall not decay to a pointer
Category: Required
Analysis: Decidable,Single Translation Unit
Rationale
An object of array type decays to a pointer when it is passed as a function argument. As a consequence, it becomes more difficult to detect array
bounds errors as the array’s bounds are lost.
If a design requires arrays of different lengths, then measures shall be taken to ensure that the dimensionality is maintained.
Note: M23_356: MISRA C++ 2023 Rule 11.3.1 recommends that C-style arrays should not be used as better options are
available in C++.
Exception
Passing a string literal as an argument to a function that expects a pointer to character parameter is permitted, as the literal is guaranteed to
end with a sentinel character (of value 0) which can be used to detect the end of the array.
Example
void f1( int32_t p[ 10 ] ); // Array will decay to pointer
void f2( int32_t * p ); // Array will decay to pointer
void f3( int32_t ( &p )[ 10 ] ); // Only accepts arrays of 10 elements
template< size_t N > // Accepts arrays of any size, with the
void f4( int32_t ( &p )[ N ] ); // size being automatically deduced
void f5( initializer_list< int32_t > l );
void log( char const * s );
void log( string_view s );
Note: it is also possible to deduce the size of an array argument without changing the function into a template. For example, an
intermediate class can be used to wrap the array, with the constructor deducing the size using the same technique as shown in f4 (above).
Arguments can then use this wrapper class, avoiding the array to pointer decay. The std::span class that has been introduced in C++20
uses this idiom.
void b()
{
int32_t a[ 10 ];
f1( a ); // Non-compliant - dimension lost due to array to pointer conversion
f2( a ); // Non-compliant - dimension lost due to array to pointer conversion
f3( a ); // Compliant - dimension of 10 matches that of the parameter
f4( a ); // Compliant - dimension deduced to be 10
f5( { 1, 2 } ); // { 1, 2 } is an initializer_list, not an array
log( "Hello" ); // Compliant by exception
char const msg[] = "Hello";
log( msg ); // Non-compliant - not a literal
string_view msg2 = "Hello"sv; // Compliant by exception - the literal operator
// has a string literal as an argument
log( msg2 ); // msg2 is a string_view, not an array
}
Copyright The MISRA Consortium Limited © 2023