Логический операнд Misra-C 2012, правило 10.1, который используется в случае, когда выражение имеет логический тип
Следующие строки генерируют нарушения Мисры.
unsigned int u16_a;
unsigned char u8_b;
if (u16_a && u8_b) // Generates Misra-C 10.1 violation.
(u16_a) ? 2 : 1 //Generates Misra-C 10.1 violation.
Нарушение говорит, что операнд имеет существенный подписанный тип, но должен быть логического типа.
Для 1-го нарушения, если я наберу приведение к типу _Bool, это не приведет к переполнению, так как я помню, что тип данных bool равен 1 байту.
Для 2-го нарушения попробовал это:
(u16_a == 0)? 1 :2 // does this work
Я довольно новичок в рассмотрении нарушений MISRA и перепутал большинство нарушений. Заранее спасибо.
3 ответа
По сути, MISRA-C хочет, чтобы мы рассматривали логические / реляционные операторы так, как будто они возвращали тип bool (как в C++), и в целом "притворялись", что C имеет отдельный тип bool, который отделен от целых чисел. Это повышает безопасность типов при использовании инструментов статического анализа.
Это означает, что вы должны быть явными с проверками на ноль:
if ( (u16_a!=0u) && (u8_b!=0u) )
а также
(u16_a!=0) ? 2u : 1u
Или желательно что-то более читабельное:
bool b_a = u16_a!=0u;
bool b_b = u8_b!=0u;
if(b_a && b_b) // MISRA compliant, operands are essentially boolean types
Использованиеif ( (u16_a !=0u) && (u8_b != 0u) )
вместоif (u16_a && u8_b)
для первого примера.
Для последнего:(u16_a == 0)? 1 :2
кажется, все в порядке для меня.
Суть в том, что весь смысл этого требования MISRA: "указать явно при сравнении со значением, а не полагаться на значения по умолчанию".
Стандарт C гласит:
6.3.1.2 Булев тип
1 Когда любое скалярное значение преобразуется в _Bool, результат равен 0, если значение сравнивается равным 0; в противном случае результат равен 1.
Так что приведение к _Bool делает правильную вещь. (x != 0)
может быть более читабельным, чем ((_Bool)x)
хоть.