Данное диагностическое правило основано на руководстве 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" \
, ....) )
Данная диагностика классифицируется как:
|