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

Диагностическое правило основано на руководстве [MISRA](https://misra.org.uk/) \(Motor Industry Software Reliability Association\) по разработке программного обеспечения\.

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

Стандарт C требует, чтобы макросы целочисленных констант минимальной ширины \(пункт 7\. 20\. 1\.2 стандарта [C11](https://open-std.org/JTC1/SC22/WG14/www/docs/n1570.pdf#page=308)\) раскрывались в [integer constant expression](https://en.cppreference.com/w/c/language/constant_expression.html)\. Это выражение \(пункт 7\.20\.4\.3 стандарта [C11](https://open-std.org/JTC1/SC22/WG14/www/docs/n1570.pdf#page=312)\) должно подходить для использования с директивами `#if`, а также его тип должен быть таким же, как если бы к аргументу макроса был применён [integer promotion](https://en.cppreference.com/w/c/language/conversion.html#Integer_promotions)\.

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

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

```cpp
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](https://en.cppreference.com/w/c/language/generic.html) выберет ассоциацию `function_int(int value)` вместо ожидаемой `function_u8(uint8_t value)`\.

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

```cpp
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));
}
```