We are using Parasoft Static Analysis with MISRA C 2004 checker turned on.
The software is an embedded system. We like to describe constants as follows:
[1] #define MOTOR_ON (1 << 9)
This would show that the 9th bit in the register should be a 1 to turn on the motor.
The expression is failing MISRA, so we changed it:
[2] #define MOTOR_ON (1U << 9U)
The changes convert to unsigned integer constants because shifting is best done with unsigned integers.
The expression in statement 2, is still failing because of the right hand operator (9U) needs checking. According to MISRA, if the right hand operator is larger than the bit width of the underlying type of the left hand operator, there is a problem.
The base of the problem is that 1U has an underlying type of unsigned char
or 8-bits.
The register we are writing to is 16-bits, so theoretically there is not an issue.
How can I change the expression in [2] so that it passes MISRA C 2004, preferring not to use casts?
I'm using IAR Embedded Workbench with an ARM7TDMI processor in 8/32 bit mode.
Edit 1: Example code.
void turn_on_motor(void);
#define MOTOR_ON (1U << 9U)
void turn_on_motor(void)
{
uint16_t * const p_motor_control = (uint16_t *)(0x01234567U);
*p_motor_control = MOTOR_ON;
}
Error text: Constant used as the right-hand operand of a shift operator shall be limited.
From the MISRA Rule documentation provided by Parasoft:
Rule reports a violation if:
- the right-hand operand is a constant with negative value or with value that
exceeds the length (in bits) of the left-hand operand
- the right-hand operand is not a constant and is not checked by specific
pattern
You could also simply circumvent the shifting issue by using
#define MOTOR_ON ((uint16_t)512U) /* 1 << 9 = 2^9 */