Main Content

MISRA C++:2023 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

Since R2024b

Description

Rule Definition

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.

Rationale

The C++ standard library functions localeconv, getenv, setlocale or strerror returns a pointer to a buffer:

  • localeconv returns a struct lconv* object, which points to a structure that includes various char* pointers.

  • getenv, setlocale and strerror returns a char* pointer.

Modifying the pointer returned by these functions results in undefined behavior. To avoid undefined behavior, assign the returned value of these functions to a const-qualified pointer. Any attempt to modify the const pointer is then detected by the compiler. Avoid using these functions using function pointers.

If modification to the return values are required, make a non-const copy of the const-qualified object and then modify the copy.

Polyspace Implementation

Polyspace® reports a violation of this rule if you assign the output of these functions to a non-const pointer:

  • localeconv,

  • getenv,

  • setlocale,

  • strerror

A violation is also reported if you take the address of any of the preceding functions.

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#include <cstdlib>
#include <cstring>
#include <clocale>
char* (*globalptr_on_get_env)(const char*) = std::getenv;         /* Non-compliant */

typedef void (*fctptr)(int);

void getfct(fctptr);

void nonconst_buffer(void)
{
    char* s1 = std::setlocale(LC_ALL, 0);    /* Non-compliant */
    struct lconv* conv = std::localeconv();  /* Non-compliant */
    s1[ 1 ] = 'A'; /* Non-compliant. Undefined behavior */
    conv->decimal_point = "^"; /* Non-compliant. Undefined behavior */
}

void const_buffer(void)
{
    char str[128];
    (void) std::strcpy(str, std::setlocale(LC_ALL, 0));     /* Compliant */
    const struct lconv* conv = std::localeconv();      /* Compliant */
   // conv->decimal_point = "^";                    /* Fails compilation */
}

void func(void)
{
    const struct lconv* conv = std::localeconv();  /* Compliant */
    conv->grouping[ 2 ] = 'x';                /* Non-compliant */
}


In the above example:

  • In the function nonconst_buffer(), the pointers returned std::setlocale() and std::localeconv() to non-const pointers. This use of the functions is not a constraint violation and is allowed by compilers. Assigning the pointer returned by these functions allows modifying the buffer pointed by the returned pointer, which is undefined behavior. Polyspace reports a violation.

  • Taking the address of std::getenv() can result in undefined behavior. Polyspace reports a violation.

  • The usage of a const-qualified pointer in the function func() gives compile time protection of the value returned by localeconv() but the same is not true for the strings it references. Modification of these strings is not compliant with this rule and Polyspace reports a violation.

  • In the function const_buffer(), the return value of std::localeconv() is assigned to a const pointer, which is not a violation of this rule. Copying the return value of these function to a non-const object is also compliant with this rule.

Check Information

Group: Localization library
Category: Mandatory

Version History

Introduced in R2024b