简体   繁体   中英

MISRA-C rule 10.5

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 constant 0U is unsigned 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 an unsigned int to an unsigned int . No lvalue conversion through assignment or other such implicit assignment takes place. The underlying type remains unsigned 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.


From what i understand, the idea is to have to maximum value of an unsigned int

Very likely.

However, i would like to know if there is something wrong with this code.

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 is uint32_t val .

uint16_t val2 = (uint16_t)(~0U);

This is MISRA compliant code. The underlying type of the assignment expression is uint16_t . Casting to uint16_t is correct and proper practice. Again, your tool is broken.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM