Оценка аргумента тернарного оператора в C

Я работал с некоторым кодом, чтобы обеспечить соответствие MISRA. Проблема с этим фрагментом кода:

Operands shall not be of an inappropriate essential type. The operand of the ? operator is of an inappropriate essential type category unsigned. 

Я предполагаю, что проблема заключается в том, что первый аргумент является типом данных без знака, а не логическим, что означает, что исправление, приведенное ниже, будет работать.

Оригинал,

 return (uint32Var & 0x80000000u) ? 0u : 1u;

Мое изменение кода,

 return ( (uint32Var & 0x80000000u)!=0u ) ? 0u : 1u;

Правильно ли это изменение? Меня беспокоит изменение функциональности кода, но, насколько мне известно, по крайней мере, в логике if операнд оценивается как numVar != 0 внутри оператора if ( numVar ).


person user145760    schedule 23.07.2019    source источник
comment
Вы можете вообще избежать тернарного оператора, например return 0 == (uint32Var & 0x80000000u);. (Я понятия не имею, соответствует ли это правилам MISRA (ble).)   -  person Ian Abbott    schedule 23.07.2019


Ответы (2)


Это безопасно.

Вы будете сравнивать беззнаковый 32-битный:

(uint32Var & 0x80000000u)

К unsigned int:

0u

Обычные арифметические преобразования применяются, чтобы гарантировать, что независимо от фактических типов, задействованных здесь, вы будете сравнивать значения типов, которые по крайней мере достаточно велики, чтобы содержать беззнаковые 32-битные.

Значение (uint32Var & 0x80000000u) является ложным, если оно равно 0, в противном случае - истинным. Сравнение значения с 0 имеет эффект, и результат 0, если сравнение равно, в противном случае результат 1 является эквивалентным поведением.


Еще одно замечание: значение, которое вы в конечном итоге используете для первого операнда тернарного оператора, не является bool, это int. Оператор != возвращает значение int либо 0, либо 1.

person Thomas Jager    schedule 23.07.2019

Я предполагаю, что проблема заключается в том, что первый аргумент является типом данных без знака, а не логическим, что означает, что исправление, приведенное ниже, будет работать. / - /

Правильно ли это изменение?

да. То есть он сделает код совместимым с MISRA. Предупреждение действительно касается использования не-логического типа для 1-го операнда.

Однако, предполагая, что функция возвращает uint32_t, вы можете просто написать:

return (uint32_t) !(uint32Var & mask);

(mask поскольку MISRA, как и все остальные, не рекомендует использовать магические числа.)

Эквивалентные, а также совместимые с MISRA-C:

return ~uint32Var >> bits; // where bits in this case is 31

Обычно оператор ~ неприятен при написании кода компиляции MISRA, но он совершенно безопасен, когда вы используете беззнаковый целочисленный тип, который не является маленьким целочисленным типом, например uint32_t.

person Lundin    schedule 03.08.2019