This question already has an answer here:
- MISRA C:2004, error with bit shifting 3 answers
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
My advice is to define a macro that hides the ugly casting, but then go ahead and do the ugly casting to make MISRA happy.
Something like:
Then in your actual code:
EDIT: In a comment below, @Lundin says that MISRA will complain about function-like macros. I've never used MISRA so I didn't know that.
A quick Google search finds that MISRA has special comments you can add to your code to disable warnings. This suggests two possibilities:
In your header file where you define
LSHIFT()
andRSHIFT()
and any other bit-manipulating macros, wrap the macro definitions in the MISRA warning disable comments.In your source file where you want to put the bit-shifting, add MISRA warning disable comments and just put your code as you had it before.
http://www.gimpel.com/Discussion.cfm?ThreadMode=Prev&ThreadID=2261
If I'm understanding correctly, MISRA has global enable/disable but does not have disable followed by "put it back the way it was". So, the comments to disable and then enable will always globally enable the check, so ideally these magic comments shouldn't be in a header file.
So I guess my suggestion now is to put your original bit shifting code int a .C source file, and put the magic comments to disable/enable the MISRA warnings around the bit shifting code.
The value of expression is being assigned to an object with a narrower type. “1U << 9U” results in only preserving the low-order bits.
“Making MISRA happy” with ugly casting won’t change this fact, though a poor tool might be gamed, it shouldn’t.
The straightforward solution is to use an explicit cast :
but if you believe the “shift is better for readability” then simply turn off the rule for this case and document the reasoning. The deviation process is perfectly fine (and encouraged) in MISRA compliant development, if fact complete conformance is impossible. You have to have a deviation management process to be fully compliant. Evidence of awareness is the goal, not evidence of conformance.
BTW, @Thomas, you are right, this is not an exact duplicate of MISRA C:2004, error with bit shifting which you also wrote. Though it is a Rule 10.3 violation, the concepts of “underlying type” described does little to help understand the intent of this warning for this specific question. My suggestion to all is taking a look at the description for Rule 10.3 in the latest version of MISRA-C:2012 (found here: http://misra.org.uk ) which makes the concepts and intent much more clear for engineers and tool makers.
You could also simply circumvent the shifting issue by using