Логический операнд 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) хоть.

Другие вопросы по тегам