Мишра нарушение 12,6
Как избавиться от нарушения MISRA по следующему утверждению
typedef unsigned char boolean;
boolean A, B;
A = !B;
Операнд логический! оператор не является "булево эффективным" выражением. MISRA-C: Правило 12.6 2004 года; СПРАВКА - ISO:C90-6.3.3.3. Унарные арифметические операторы
5 ответов
Если вы прочитаете правило 12.6, в приложении будет написано "проверьте логические выражения". Там мы можем прочитать
"Логические значения по принудительному применению могут быть введены путем реализации механизма принудительного применения определенного типа с использованием инструмента. Логический тип может быть связан с определенным определением типа и затем может использоваться для любых объектов, которые являются логическими. Это может принести много преимуществ, особенно если инструмент проверки может его поддерживать, и, в частности, он может помочь избежать путаницы между логическими операциями и целочисленными операциями ".
MISRA-C:2004 предполагает C90, а в C90 нет типа bool, вы должны определить его самостоятельно, как вы это сделали. Поскольку ваше намерение состоит в том, чтобы иметь тип, который по сути является логическим, код просто в порядке. Фактически, ваш код соответствует рекомендациям MISRA, помимо обязательных.
Проблема заключается в вашем инструменте: он либо не поддерживает разрешение определенного логического типа в соответствии с рекомендациями MISRA, либо неправильно настроен.
Просто... не используйте !
на вещи, которые не являются логическими. Просто потому, что ваш typedef назван boolean
не значит, что это так; это все еще unsigned char
,
Вы могли бы написать:
if (b == 0) A = 1;
else A = 0;
Я не думаю, что MISRA допускает троичных операторов (может быть не так; не эксперт), но если это так, вы могли бы написать:
A = (b == 0) ? 1 : 0;
Вы пробовали идиому !!
для преобразования значений в логическое значение:
bool bool_val = !!int_val;
Тогда надуманный следующий код может работать:
A = !(!!B) // B is "cast" within the parenthesis then we apply the "NOT"
Хотя стандарт ISO:C90 гласит, что операнд может быть любого скалярного типа! оператор всегда выдает значение 0 или 1; базовый тип (в терминах MISRA-C:2004) считается по сути логическим, а операнд - нет. Поскольку оператор интерпретирует свой операнд в логическом смысле, сравнивая его с try:
A = (B==0);
которые делают логическое сравнение явным. Кроме того, в зависимости от инструмента может существовать механизм принудительного применения логического типа, который можно настроить для этого typedef.