I got a MISRA-C warning of Rule 10.8: A composite expression of 'essentially unsigned' type (unsigned char) is being cast to a wider unsigned type, 'unsigned short'.
This warning was detected with the following code.
void Fucntion(unsigned char isSwitchOn) {
unsigned short switchMask = 0U;
switchMask |= (unsigned short)(isSwitchOn & 1U) << 1;
Why was a warning detected? Also, does this code cause problems?
I think that the expression (isSwitchOn & 1U) is converted to an int type and calculated, and the result is truncated and stored as an unsigned short type. Thinking like that, the warning seems unnatural to me.
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.