V2653. MISRA. The small integer variants of the minimum-width integer constant macros should not be used.

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

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

Стандарт C требует, чтобы макросы целочисленных констант минимальной ширины (пункт 7. 20. 1.2 стандарта C11) раскрывались в integer constant expression. Это выражение (пункт 7.20.4.3 стандарта C11) должно подходить для использования с директивами #if, а также его тип должен быть таким же, как если бы к аргументу макроса был применён integer promotion.

Использование макросов целочисленных констант минимальной ширины не рекомендуется, так как приводит к путанице с подставляемыми типами.

Рассмотрим следующий пример:

void function_u8(uint8_t value){}
void function_int(int value) {}

#define MACRO_U8(Z) _Generic((Z)              \
                     , uint8_t: function_u8   \
                     , default: function_int)(Z)

void foo(void)
{
  MACRO_U8(UINT8_C(8));    // <=
}

UINT8_C — это макрос в языке C, предназначенный для обозначения беззнаковых 8-битных целочисленных констант. Он определяется в стандартных заголовочных файлах, таких как <stdint.h>, и используется для обеспечения переносимости кода между различными платформами и компиляторами.

Ожидается, что результат раскрытия макроса UINT8_C будет иметь тип uint8_t. Однако после применения integer promotion, так как ранг uint8_t меньше, чем int, результат будет таким же, как если бы аргумент был подставлен в код без изменений как целочисленная константа 8.

В результате _Generic selection выберет ассоциацию function_int(int value) вместо ожидаемой function_u8(uint8_t value).

Исправленный пример:

void function_u8(uint8_t value){}
void function_int(int value) {}

#define MACRO_U8(Z) _Generic((Z)              \
                     , uint8_t: function_u8   \
                     , default: function_int)(Z)

void foo(void)
{
  MACRO_U8((uint8_t)(8));
}

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

  • MISRA-C-2023-7.6