I have the following static analysis report that the code is not compliant for MISRA-C rule 10.5 :
Results of ~ and << operations on operands of underlying types unsigned char and unsigned short should immediately be cast to the operand's underlying type
The code is :
unsigned val = ~0U;
From what i understand, the idea is to have to maximum value of an unsigned int
which can also be achieved by unsigned val = UINT_MAX;
from <limits.h>
.
However, i would like to know if there is something wrong with this code.
To me, 0U
is of type unsigned integer and has a value of 0
, then operator ~
is applied which gives a result of type unsigned int
with all bits set to 1
and finally it is copied to an unsigned int
.
I would say that no integer promotion happens here before the operator ~
because we already have an unsigned int
.
Moreover, the tool gives the same report somewhere else in the code :
uint16_t val2 = (uint16_t)(~0U); /* cast is explicit so what is wrong here ? */
I am not sure whether or not this code needs a fix for both "offending" lines.
The concept underlying type was used in the older MISRAs, nowadays deprecated and replaced with essential type categories. The definition of underlying type is the type that each of the operands in an expression would have if not for implicit type promotion.
In the expression
~0U
, the type of the integer constant0U
isunsigned int
. It is not a small integer type, so no integer promotion takes place upon~
. The underlying type is the same as the actual C language type,unsigned int
.unsigned val = ...
assigns anunsigned int
to anunsigned int
. No lvalue conversion through assignment or other such implicit assignment takes place. The underlying type remainsunsigned int
.Thus if your tool gives a warning about no cast to underlying type on the line
unsigned val = ~0U;
, your tool is simply broken.Very likely.
No, nothing is wrong with your code. However, other MISRA rules require you to replace the default "primitive types" with types from
stdint.h
(or equivalent on pre-C99 compilers). So in case this is a 32 bit system, the MISRA compliant version of your code isuint32_t val
.This is MISRA compliant code. The underlying type of the assignment expression is
uint16_t
. Casting touint16_t
is correct and proper practice. Again, your tool is broken.