Page 1 of 1

Rule 2.2 - dead code

Posted: Mon Jul 25, 2016 2:16 pm
by delta_controls
Does the following code example violate Rule 2.2, due to the left shift?

Code: Select all

#define BITSET(reg, bit)	((reg) |= (uint8_t)(1u << (bit)))
#define BIT0	0

BITSET(PORTA, BIT0); 	// PORTA is an unsigned char mapped to a specific memory address

PS - Although the function-like macro looks like a violation of Directive 4.9, it is only used in a function like port_bit_set, which is used for setting a GPIO port bit and provides argument checking.

Re: Rule 2.2 - dead code

Posted: Sat Jul 30, 2016 11:46 am
by Steve Montgomery
At first sight, I didn't believe that there was any dead code in your example. However, the question prompted me to re-read Rule 2.2 just to be sure. Having done so, I think you example does contain dead code according to the rule, even though common sense says that it doesn't.

The rule says
Any operation that is executed but whose removal would not affect program behaviour constitutes dead code
The uint8_t cast seems to satisfy this definition: it is an operator and it is certainly executed but removing it will have no effect on the program's behaviour. If that's the case, then this kind of dead code must be quite common. The essential type rules, for example, may well require insertion of casts that don't actually change the program's behaviour.

Maybe I'm misunderstanding what Rule 2.2 says but I would think that it's not intended to apply to your example.

Re: Rule 2.2 - dead code

Posted: Thu Aug 04, 2016 5:50 pm
by delta_controls
Thanks for the reply.

Having thought about this, I agree that there is no violation, since the rule is intended to be applied at statement level. As you say, if this weren't the case, there would be violations all over the place and therefore many deviations for any given project.

Re: Rule 2.2 - dead code

Posted: Wed Aug 10, 2016 6:45 am
by Steve Montgomery
Could we have an official comment from MISRA on this, namely:
  • does the example contain dead code or not?
  • if not, how does the cast operation avoid being dead given the Glossary definition?

Re: Rule 2.2 - dead code

Posted: Mon Aug 15, 2016 9:11 am
by misra-c
Thank you for your question. There are two operations of interest in this macro expansion.
Firstly there is the shift operation

Code: Select all

1u << (bit)  which is expanded to 1u << ( 0 )
And secondly the operation of the cast

Code: Select all

(uint8_t)(1u << (0))  
where the presence/absence of the cast has no effect on the value of the expression
We plan to discuss these issues at the next MISRA-C working group meeting towards the end of September and will post a response after the meeting.

The function-like macro will violate Directive 4.9. regardless as to how it is used. Replacing the macro with a function ( or inline function ) would remove the violation of rule 2.2 assuming that the function is not always called with the value 0. However it is appreciated that there may be reasons why it is not practical to use an inline function.

Re: Rule 2.2 - dead code

Posted: Fri Sep 23, 2016 9:02 am
by misra-c
There are various issues raised by the original question and subsequent discussion which we will address in turn.

1. Rule 2.2 applies to operators not statements.
It is not a question of whether a whole statement is dead code, but whether there is an operation within the expression that has no effect on the program behaviour.

2. There are two operators of interest in this macro expansion. First is the operation
1u << (bit) which is expanded to 1u << ( 0 )
The shift operation has no effect on the program behaviour since shifting any value by 0 always produces the same answer. Therefore the "<<(0)" can be removed and there is a violation of rule 2.2.

3. The second operation of interest is the cast which in this macro expansion has no effect and therefore is strictly speaking a violation of rule 2.2.
However we agree with the previous poster that this was probably not what was intended by this rule. We will revisit this issue at a later date.