# V2638. MISRA. Generic association should list an appropriate type.

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

Это правило актуально только для языка С.

Использование конструкции `_Generic` (C11) в совокупности с определёнными типами в списке ассоциаций может приводить к неожиданным результатам.

Перед тем как контролирующее выражение будет сопоставлено со списком ассоциаций, оно пройдёт цепочку неявных преобразований (lvalue conversion):

- отбрасываются `const` / `volatile` / `restrict` квалификаторы верхнего уровня;
- отбрасывается атомарность типа;
- массив будет превращён в указатель;
- функция будет превращена в указатель на функцию.

Поскольку стандарт C не накладывает никаких ограничений на типы, указанные в списке ассоциаций, может произойти ситуация, когда та или иная ветка никогда не будет выбрана. В связи с этим список ассоциаций не должен содержать любой из перечисленных ниже типов:

- `const` / `volatile` / `restrict` квалифицированный тип;
- атомарный тип;
- массив;
- функция;
- неименованная структура или объединение (могут быть обработаны только `default`-ассоциацией).

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

    #define builtin_typename(expr)                      \
      (_Generic( (expr)                                 \
         , char: "char"                                 \
         , const char: "const char"                     \
         , volatile char: "volatile char"               \
         , const volatile char: "const volatile char"   \
         , short: "short"                               \
         , const short: "const short"                   \
         , volatile short: "volatile short"             \
         , const volatile short: "const volatile short" \
         , ....) )

В коде объявляется макрос `builtin_typename`, который конвертирует переданное выражение в строковый литерал, содержащий тип выражения. Для этого перебираются все встроенные типы с комбинациями `const` и `volatile` квалификаторов. Однако контролирующее выражение после неявных преобразований никогда не будет `cv`-квалифицированным. Поэтому такая конструкция `_Generic` содержит ассоциации, которые никогда не будут выбраны.

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

    #define builtin_typename(expr) \
      (_Generic( (expr) \
         , char: "char" \
         , short: "short" \
         , ....) )

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

MISRA-C-2023-23.4