Ankit Shah
Ankit Shah

Reputation: 107

MISRA C:2004 10.5 Query

I am somewhat stucked at a part of the code that gives MISRA C 2004 10.5 violation but am not able to figure out what exactly might be the cause.

I have defined this MACRO to get the power of 2.

The code which shows the violation is

#define tmM_pow2_16bit(x)   ((tm_uint16)((tm_uint16)1U<<((tm_uint16)x)))

The message that comes from the static analysis tool is

Shift left of signed quantity (int) [MISRA 2004 Rule 10.5, required]

Thank you

Upvotes: 3

Views: 1610

Answers (3)

Lundin
Lundin

Reputation: 214780

The problem is probably that the tool can't quite figure out what the underlying type is. I suspect it thinks the underlying type is unsigned int, since that's the type of 1U.

The cast (tm_uint16)1U is superfluous - on systems where int is 32 bit or larger, this will only force a conversion to a small integer type, which will then immediately get implicitly converted to int. That would be a MISRA-C:2004 violation, as no such implicit conversions that change the signedness may occur. I recommend studying Implicit type promotion rules.

(tm_uint16)x is also superfluous, as the right operand of the shift operators take no part in determining the result of the operand.

MISRA-C:2004 compatible code should simply be this:

#define tmM_pow2_16bit(x)   ( (tm_uint16)(1U << (x)) )

Assuming x is valid for the tm_uint16 type.

(Please note that MISRA-C also discourages the use of function-like macros.)

Upvotes: 1

chqrlie
chqrlie

Reputation: 145277

The tool used to check MISRA-C compliance seems broken, but in some sense, you are indeed left shifting a signed integer type int: on architectures where int is larger than 16 bits, (tm_uint16)1U is promoted to int before the shift takes place, but there is no problem since its value is positive anyway.

Note however that there is a much worse problem in this macro: x is not parenthesized in the expansion, causing unexpected behavior for non trivial expressions such as tmM_pow2_16bit(1|2).

You can probably fix the warning by removing the unnecessary casts:

#define tmM_pow2_16bit(x)   ((tm_uint16)(1U << (tm_uint16)(x)))

If the tools still complains about potential left shifting by a quantity larger than the bit-width of int, add a mask:

#define tmM_pow2_16bit(x)   ((tm_uint16)(1U << ((x) & 15U)))

Upvotes: 0

user694733
user694733

Reputation: 16047

Most likely reason is that shift operator forces implicit promotion of (tm_uint16)1U to int type.

Remove the second cast to make sure that you shift unsigned type:

((tm_uint16)(1U<<((tm_uint16)x)))

Upvotes: 2

Related Questions