Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
No operators in #if
#1
The MISRA checker I am using is rejecting operators in #if as noted in the following code.
Code:
#define TRUE 1

#define Condition1 TRUE
#define Condition2 TRUE

#if Condition1   /* Accepted */
#endif
#if !Condition1  /* Rejected */
/* Rejection is because:
Unpermitted operand to operator '!' [MISRA 2012 Rule 10.1, required]
*/
#endif
#if Condition1 && Condition2  /* Rejected */
/* Rejection is because:
Unpermitted operand to operator '&&' [MISRA 2012 Rule 10.1, required]
*/
#endif
#if Condition1 || Condition2  /* Rejected */
/* Rejection is because:
Unpermitted operand to operator '||' [MISRA 2012 Rule 10.1, required]
*/
#endif
According to the supplier, the constant '1' (or '0' when used in the same way) is being interpreted as a signed int and therefore the operators '!', '&&' and '||' cannot be used with it.

Is the checker's interpretation correct?
Reply
#2
Yes and no.
I think rule 20.8 is more appropriate here than rule 10.1.
Can you run the snippet below through your checker?
It should be compliant this way:

Code:
#define FALSE 0
#define TRUE 1

#define Condition1 TRUE
#define Condition2 TRUE

#if Condition1
#endif
#if (Condition1 == FALSE)  
#endif
#if ((Condition1 == TRUE) && (Condition2 == TRUE))
#endif
#if ((Condition1 == TRUE) || (Condition2 == TRUE))
#endif
<t></t>
Reply
#3
Yes, that code snippet is accepted by the checker. I would expect that it would be because, for example, (0==1) is valid whether the values 0 and 1 are treated as boolean or as signed integers.
Reply
#4
Yes, according to the rationale given in rule 20.8 the controlling expression itself shall have a boolean value.
So, I hope you can simply adopt accordingly.
<t></t>
Reply
#5
Well, I could change my code to suit the checker, but that's the tail wagging the dog, isn't it?

My view is that the constants 0 and 1 on their own do not have an ET because they could be interpreted as either boolean or as signed int. It is only when an operator is applied that an ET can be assigned. So in !1, 1 has an ET of boolean but in -1, 1 has an ET of signed int. This checker has assumed that 0 and 1 are signed ints, regardless of operators, so !, && and || are not permitted. I find it hard to believe that it was the intention of the MISRA group to prohibit the use of these operators in #if, especially by doing it implicitly through the rules for ETs.
Reply
#6
I think appendix D.6 comes into play here - the preprocessor cannot be aware of the magic constants in stdbool.h (C99 has no real bool) so 0 / 1 are indeed treated as integer constants.
But now I am also interested in an official reply.
Let's wait and see.
<t></t>
Reply
#7
Using these definition eliminates the messages from the checker, which solves my problem.

#define FALSE (0!=0)
#define TRUE (0==0)
Reply
#8
Perfectly valid option:-)
<t></t>
Reply
#9
The MISRA guidelines define "code" in the Glossary as
Quote:"Code consists of everything within a translation unit that is not excluded by conitional compilation."
All guidelines apply to code after preprocessing directives have been executed, unless otherwise stated in a guideline. Therefore rule 10.1 does not apply.

Even if the examples where visible after expansion, they should not produce a 10.1 violation if the tool is configured to recognise TRUE as having an essentially boolean types (See Appendix D.6)For example:
Code:
#define TRUE 1
#define Condition1 TRUE
#define Condition2 TRUE
if ( Condition1 && Condition2  ) // No violation of rule 10.1 if TRUE is identified as an essentially boolean type
Posted by and on behalf of the MISRA C Working Group
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)