Диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.
Правило актуально только для языка C.
В языке C конструкция switch обладает достаточно свободным синтаксисом. Отсутствие строгих правил может привести к написанию сложного неструктурированного кода. Для уменьшения вероятности допущения ошибки, а также для упрощения поддержки кода стандартом MISRA вводится понятие "well-formed" switch.
Чтобы пояснить, что такое "well-formed", введём ещё два определения:
1. case-group — последовательность из одного и более идущих подряд case label (которые могут включать default), например:
case 42: //или case 1: case 2: case 300: //или case 12: default:
2. switch-clause — одно из следующего:
break;{ declarations* statements* break; }{ (declarations | statements)* break; }Где * означает повторение 0 или более раз.
Например:
x = 5; y = 19; printf("%d", x); break;
//или
{ int x; int y; x = 5; y = x + 1; printf("%d", x); break; }
//или(кроме C90)
{ int x; x = 5; int y = x + 1; printf("%d", x); break; }
С учётом введённых определений "well-formed" switch можно представить в виде:
switch (expression)
{
case-group_1: switch-clause;
case-group_2: switch-clause;
....
case-group_n: switch-clause;
}
Также есть два дополнительных требования:
default обязана присутствовать и либо стоять в начале первой case-group, либо в конце последней;case-group должно быть не меньше двух.Примеры некорректных switch-statement:
switch (n)
{
case 1:
default: // <= (1)
case 2: n++; int x = 0; x++; break; // <= (2)
case 3: { n++; break; }
}
В данном примере присутствуют следующие нарушения:
default: она должна быть либо первой в списке меток, либо последней;switch-clause после case 2: он содержит декларацию, которая не находится внутри блока.
switch (n)
{
case 10:
case 20: break;
}
В данном примере присутствуют следующие нарушения:
default;case входит в первую, то количество case-group меньше двух. В таком случае switch-case не имеет смысла.switch (count % 4)
{
case 0: do { *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while (--n > 0);
}
В данном примере (знаменитый метод Даффа) присутствуют следующие нарушения:
switch-clause: отсутствует break;case-group: метки case 3, case 2и case 1 находятся внутри switch-clause и образуют последовательность case-group, которая не находится непосредственно внутри switch-case;default.Пример "well-formed" switch:
switch (n)
{
case 1: case 2: { n = 5; } break;
case 10:
case 20: break;
case 30: { int x; x = 4; printf("%d", x); break; }
default: if (n > 6) { n++; } break;
}
Данная диагностика классифицируется как:
|