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

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

>
>
>
V2669. MISRA. Tokens that look like...
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

V2669. MISRA. Tokens that look like a preprocessing directive should not occur within a macro argument.

05 Фев 2026

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

Правило актуально только для С.

Токен, выглядящий как директива препроцессора, не должен использоваться как аргумент макроса. Использование директив препроцессора в качестве аргумента макроса ведёт к неопределённому поведению.

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

#include <stdio.h

#define PRINT(arg) printf("%s", #arg)

int main(int argc, char *argv[])
{
  PRINT(
    #ifndef FLAG
      My program prints: hello.
    #else
      My program prints: world.
    #endif 
  );
}

Программист ожидает, что в зависимости от того, определён ли макрос FLAG, в stdout будет выведено или My program prints: hello, или My program prints: world. Поскольку поведение не определено, компилятор вправе сделать в этой ситуации всё, что хочет.

Если программа собрана с помощью GCC или Clang без макроопределения FLAG, то результат совпадёт с одним из вариантов, который ожидает программист:

My program prints: hello.

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

#ifndef FLAG My program prints: hello. #else My program prints: world. #endif

Исправленный код:

#include <stdio.h>

#define PRINT(arg) printf("%s", #arg)

int main(int argc, char *argv[])
{
#ifndef FLAG
  PRINT(My program prints: hello.);
#else
  PRINT(My program prints: world.);
#endif 
}

Теперь все программы, собранные разными компиляторами, выводят текст одинаково в зависимости от макроопределения FLAG.

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

  • MISRA-C-2012-20.6
  • MISRA-C-2023-20.6