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_tbefore applying~doesn't make any sense, it can even be considered a bug in your case since you convert aunsigned inttouint8_t, which in turn gets implicitly promoted tointand you end up with a signed-1which 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)0Uis 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.