When I run static code analysis it says:
Bitwise operator "~" has a signed operand "(uint8)0U"
.
How come this operand is signed while I am explicitly casting it to uint8
which is equivalent to unsigned char
and also postfixing it with literal U
which stands for unsigned integer?
See Implicit type promotion rules, the ~ operator applies the integer promotions on its operand. Or study appendix C of MISRA C:2012.
MISRA or not, casting to a small integer type such as
uint8_t
before applying~
doesn't make any sense, it can even be considered a bug in your case since you convert aunsigned int
touint8_t
, which in turn gets implicitly promoted toint
and you end up with a signed-1
which isn't intended.However, from a MISRA C:2012 perspective, a static analyser should only bother to check the type before implicit promotion. As per rule 10.1 the only allowed operand of
~
is one that's essentially unsigned. That is, code such as~(uint8_t)0U
is strange and bad, but as far as I can tell, MISRA C:2012 compliant.The older deprecated MISRA C:2004 had a requirement that you should cast the result to what that version of MISRA called underlying type - the type an expression would have had if not for implicit promotion. So you'd write
(uint8_t)~0U
. This rule of underlying type was a bit blunt and misguided however, the current concept of essential type works better and is easier to understand. If you have an old tool checking for MISRA C:2004 compliance then the warning makes perfect sense.Either way, the recommended practice is to always cast the result of
~
to the unsigned type intended to be used by the expression. That way you can't go wrong.