Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top

Вебинар: Инструменты для разработчиков игр и не только - 26.02

>
>
>
V2671. MISRA. Pointers returned by...
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

V2671. MISRA. Pointers returned by the function 'localeconv' / 'getenv' / 'setlocale' / 'strerror' should be used as if they have pointer to const-qualified type.

05 Фев 2026

Диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.

Правило актуально только для языка C.

Указатели, возвращаемые из функций localeconv, getenv, setlocale, strerror, должны быть использованы как указатели на const-квалифицированный тип.

Согласно стандарту C поведение не определено (C23, Annex J, J.2, пп. 119, 121, 189), если программа модифицирует:

  • объект типа lconv через указатель, полученный путём вызова localeconv;
  • строку через указатель, полученный путём вызова одной из функций: getenv, setlocale или strerror.

Рассмотрим пример:

char *GetPath(void)
{
  char *path = getenv("PATH"); // <=
  if (path == NULL)
  {
    return NULL;
  }

  for (size_t i = 0; i < strlen(path); ++i)
  {
    if (path[i] == '\\')
    {
      path[i] = '/';
    }
  }

  return path;
}

Из переменной окружения PATH получают значение с помощью функции getenv. Она возвращает указатель на внутренний буфер, в котором программист заменяет все вхождения символа \ на /. Затем полученный буфер возвращают из функции через указатель. Так как это внутренний буфер, используемый стандартной библиотекой, он может быть использован другими функциями. Его прямая модификация ведёт к неопределённому поведению.

Корректная реализация предполагает копирование строки в отдельный буфер, который затем будет модифицирован:

char *GetPath(void)
{
  const char * const path = getenv("PATH");
  if (path == NULL)
  {
    return NULL;
  }

  size_t len = strlen(path);
  char *buffer = malloc((len + 1) * sizeof(char));
  if (buffer == NULL)
  {
    return NULL;
  }

  buffer[len] = '\0';

  for (size_t i = 0; i < len; ++i)
  {
    if (path[i] == '\\')
    {
      buffer[i] = '/';
    }
    else
    {
      buffer[i] = path[i];
    }
  }

  return buffer;
}

Данная диагностика классифицируется как:

  • MISRA-C-2023-21.19