Why was a warning detected?
Let us look at
void Fucntion(unsigned char isSwitchOn) {
unsigned short switchMask = 0U;
switchMask |= (unsigned short)(isSwitchOn & 1U) << 1;
isSwitchOn
, being lower rank than 1U
, goes through the usual arithmetic conversion (C11 §6.5.10 3) to the type unsigned
to match the type of 1U
.
isSwitchOn & 1U
is calculated, the result type is unsigned
.
Cast (unsigned short)
is applied to the unsigned
result - this step seems strange. This is the MISRA-C warning of Rule 10.8. There is no need for the cast. The composite type unsigned
is unnecessarily being narrowed to unsigned short
.
The (unsigned short)
result is prepared for shifting and integer promotions are performed on each of the operands of the <<
. So the (unsigned short)
is promoted to int
or possibly unsigned
if USHRT_MAX > INT_MAX
. Let us assume int
.
Now the shift of an int
occurs. Result is type int
.
The int
is applied to a unsigned short
.
Also, does this code cause problems?
I do not see in this case, the cast causing an issue other than it is WET programing. Had the result been unsigned switchMask
, yes then the shifted out bit would have been lost.
It makes more sense to cast the result after the shift. @Myst
switchMask |= (unsigned short)((isSwitchOn & 1U) << 1);
Or avoid other potential warnings with
switchMask = (unsigned short)(switchMask | ((isSwitchOn & 1U) << 1));
I think that the expression (isSwitchOn & 1U)
is converted to an int type and calculated
No, the expression (unsigned short)(isSwitchOn & 1U)
is converted to an int type and calculated.
Note: It is dubious that unsigned char isSwitchOn
and unsigned short switchMask
are not the same type.
switchMask |= ...
accesses an uninitialized variable. – Stephan Lechner(unsigned short)(isSwitchOn & 1U) << 1
vs(unsigned short)((isSwitchOn & 1U) << 1);
... – Myst