I am writing a code under the MISRA rule. I am getting a MISRA error for the below expression
check_Val = ( ~( 0x000Fu << Src_Data ) ); //where Src_Data is uint8 and check_Val is uint32.
I analyzed the error
Violates MISRA 2004 Required Rule 10.1, Implicit conversion of complex integer expression
Since check_Val is uint32
, the Lf should fit on it. Then why it is giving an error.
Rule 10.1 is concerned with implicit promotion of integers, by using the MISRA:2004 concept of "underlying type", that is, the intended type of the expression. It was a weird concept which lead to numerous superfluous casts, this has been fixed in MISRA:2012.
The underlying type of your expression is that of the integer literal 0x000Fu
. For integer literals it stated that underlying type is the smallest possible type that is capable of representing the object (see p40-41). So the underlying type of 0x000Fu
will be uint8_t
, because it can fit in a byte and it is of unsigned type.
Even though, as far as the C language and the compiler are concerned, that integer literal is actually of type unsigned int
and no promotions will occur. MISRA:2004 doesn't care.
Meaning that you have to cast the operand to uint32_t
before the operation (to bypass rule 10.1) or cast it to uint8_t
after the operation (to sate 10.1 and also 10.5 regarding shifts). I suggest you cast it to uint32_t to get rid of the problem.
Fixed code should therefore be
check_Val = ~( (uint32_t)0x000Fu << Src_Data );
Also, since both operands of a shift operator are integer promoted, the right-hand operator gets implicitly promoted to int
as well. That promotion can never cause harm, and I'm not sure it is even a MISRA violation, but I suppose it could be causing warnings too. In that case, you would also have to cast the right operand:
check_Val = ~( (uint32_t)0x000Fu << (uint32_t)Src_Data );
I would recommend to use MISRA:2012 if possible, where these rules have been clarified and the "underlying type" concept has been replaced by one which doesn't lead to so many pointless casts.