Assuming 32 bit int
type, then:
MISRA-C:2012 just requires that the type the operands of a shift operator must be "essentially unsigned" (rule 10.1). By that they imply that an implicit promotion from unsigned short
to int
can never be harmful, since the sign bit can't be set by that promotion alone.
There's further requirement (MISRA-C:2012 rule 10.4) that both operands in an expression where "the usual arithmetic conversions" are performed (see Implicit type promotion rules) should be of the same essential type category. "The usual..." apply to most binary operators in C, but not to the shift operators, they are a special case.
For the shift operators, the C standard 6.5.7 lists this special rule:
The integer promotions are performed on each of the operands. The type of the result is
that of the promoted left operand.
This means that some_unsigned_short >>
is MISRA-C compliant and the type of bit
is actually irrelevant (as long as it is a positive number). However, rule 10.1 requires that the right operand must be unsigned too (to prevent nonsense stuff like >> -1
). Even if the right operand is also unsigned, the expression is a bit questionable still - preferably you should cast the left operand to a large integer type (like uint32_t
) before shifting.
Ignoring the right operand of shift, (some_unsigned_short >> some_int) & 1u
is still not MISRA-C compliant, because it is mixing signed and unsigned essential type categories int & unsigned int
which is not allowed neither by rule 10.1 nor rule 10.4 - the &
operator does apply the usual arithmetic conversions. So this needs to be fixed to either
(uint32_t)(some_unsigned_short >> some_unsigned_int) & 1u
or preferably
((uint32_t)some_unsigned_short >> some_unsigned_int) & 1u
Either is MISRA compliant.
However, in the case you have 16 bit int
everything turns different. The unsigned short
operand of the shift then gets integer promoted to unsigned int
rather than int
, as a special case in the integer promotion rule (the link I gave above explains that special case). In that case, after promotion we end up with some_unsigned_int >> ...
, which is fine. And then (some_unsigned_int >> ...) & 1u
is fine too.