This rule is part of MISRA C++:2023.
Usage of this content is governed by Sonar’s terms and conditions. Redistribution is
prohibited.
Rule 10.1.1 - The target type of a pointer or lvalue reference parameter should be const-qualified appropriately
Category: Advisory
Analysis: Decidable,Single Translation Unit
Amplification
The target type of a named pointer or reference parameter should be const-qualified, unless:
- It is not an object type; or
- The parameter is assigned to a pointer or reference with a non-const target type; or
- The target object is modified within the function.
For the purposes of this rule, an object is also considered to be modified if it is passed as a pointer to non-const parameter or a non-const
reference parameter, including use as the implicit this parameter of a non-const member function.
This rule does not apply to parameters:
- That are unnamed; or
- Of virtual functions; or
- Of function templates; or
- Of functions or lambdas declared within the scope of a template.
Note: this rule also applies to pointer parameters declared using array syntax.
Rationale
Consistent application of this guideline results in function signatures that more accurately reflect the behaviour of the functions within the
project, making it less likely that a developer will falsely assume that a call will not result in the modification to an object.
The rule does not apply to virtual functions as different overrides of the function may or may not modify the target object, and all overrides will
need to omit const-qualification if one or more of the overrides requires that the target type be non-const. Similarly, for templates, only some
instantiations may modify the target object.
Exception
This rule does not apply to main whose signature, which does not use const-qualification, is defined within the C++ Standard.
Example
void f1( int8_t * p1, // Compliant - *p1 modified
const int8_t * p2, // Compliant - *p2 not modified, but is const
int8_t * p3, // Non-compliant - *p3 not modified, no const
int8_t * const p4, // Non-compliant - *p4 not modified, no const
int8_t a[3] ) // Non-compliant - 'a' decays to int8_t *
{
*p1 = *p2 + *p3 + *p4 + a[ 2 ];
}
auto & f2( int32_t & i, // Compliant
int32_t && j, // Rule does not apply - rvalue reference
int32_t & ) // Rule does not apply - unnamed parameter
{
return i; // Assigning to non-const reference
}
auto f3( std::vector< int32_t > & x ) // Compliant - even though x.begin has an
{ // equivalent const overload
return x.begin(); // Non-const member function
}
auto f4( std::vector< int32_t > & x ) // Non-compliant
{
return x.cbegin(); // Const member function
}
template< typename T >
struct A
{
void foo ( T & t, // Rule does not apply - in template scope
int32_t & i ) // Rule does not apply - in template scope
{
t.f( i ); // t and/or i may or may not be modified,
} // depending on the signature of T::f
};
Copyright The MISRA Consortium Limited © 2023