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 a unsigned int
to uint8_t
, which in turn gets implicitly promoted to int
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.