This rule is part of MISRA C++:2023.
Usage of this content is governed by Sonar’s terms and conditions. Redistribution is
prohibited.
Rule 25.5.2 - The pointers returned by the C++ Standard Library functions localeconv, getenv, setlocale or
strerror must only be used as if they have pointer to const-qualified type
[clocale.syn]
[cstdlib.syn]
[cstring.syn]
[C11] / 7.11.1.1; Undefined 8
[C11] / 7.11.2.1; Undefined 8
[C11] / 7.22.4.6;
Undefined 4
[C11] / 7.24.6.2; Undefined 3
Category: Mandatory
Analysis: Decidable, Single Translation Unit
Amplification
The localeconv function returns a pointer of type struct lconv *. This pointer must be regarded as if it had type
const struct lconv *.
A struct lconv object includes pointers of type char * and the getenv, setlocale, and
strerror functions each return a pointer of type char *. These pointers are used to access C-style strings (null-terminated
arrays of type char). For the purposes of this rule, these pointers must be regarded as if they had type const char *.
The addressed of these functions shall not be taken.
Rationale
The C++ Standard states that undefined behaviour occurs if a program modifies:
- The structure pointed to by the value returned by
localeconv;
- The strings returned by
getenv, setlocale or strerror.
Note: the C++ Standard does not specify the behaviour that results if the strings referenced by the structure pointed to by the
value returned by localeconv are modified. This rule prohibits any changes to these strings as they are considered to be undesirable.
Treating the pointers returned by the various functions as if they were const-qualified allows an analysis tool to detect any attempt to modify an
object through one of the pointers. Additionally, assigning the return values of the functions to const-qualified pointers will result in the compiler
issuing a diagnostic if an attempt is made to modify an object.
Note: if a modified version is required, a program should make and modify a copy of any value covered by this rule.
Preventing the addresses of these functions from being taken allows compliance checks to be decidable.
Example
The following examples are non-compliant as the returned pointers are assigned to non const-qualified pointers. Whilst this will not be reported by
a compiler (it is not ill-formed), an analysis tool will be able to report a violation.
void f1()
{
char * s1 = setlocale( LC_ALL, 0 ); // Non-compliant
struct lconv * conv = localeconv(); // Non-compliant
s1[ 1 ] = 'A'; // Undefined behaviour
conv->decimal_point = "^"; // Undefined behaviour
}
The following examples are compliant as the returned pointers are assigned to const-qualified pointers. Any attempt to modify an object through a
pointer will be reported by a compiler or analysis tool as this is ill-formed.
void f2()
{
char str[ 128 ];
( void ) strcpy( str,
setlocale( LC_ALL, 0 ) ); // Compliant - 2nd parameter to
// strcpy takes a const char *
const struct lconv * conv = localeconv(); // Compliant
conv->decimal_point = "^"; // Ill-formed
}
The following example shows that whilst the use of a const-qualified pointer gives compile time protection of the value returned by
localeconv, the same is not true for the strings it references. Modification of these strings can be detected by an analysis tool.
void f3()
{
const struct lconv * conv = localeconv(); // Compliant
conv->grouping[ 2 ] = 'x'; // Non-compliant
}
Copyright The MISRA Consortium Limited © 2023