Main Content

MISRA C:2023 Rule 20.9

All identifiers used in the controlling expression of #if or #elif preprocessing directives shall be #define'd before evaluation

Since R2024a

Description

Rule Definition

All identifiers used in the controlling expression of #if or #elif preprocessing directives shall be #define'd before evaluation.

Rationale

If attempt to use a macro identifier in a preprocessing directive, and you have not defined that identifier, then the preprocessor assumes that it has a value of zero. This value might not meet developer expectations.

Troubleshooting

If you expect a rule violation but do not see it, refer to Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#if M == 0                   /* Non-compliant - Not defined */
#endif

#if defined (M)              /* Compliant - M is not evaluate */
#if M == 0                   /* Compliant - M is known to be defined */
#endif
#endif

#if defined (M) && (M == 0)  /* Compliant
                              * if M defined, M evaluated in ( M == 0 ) */
#endif

#define XXYY 1                                          
#define ADD(a,b) a##b                                   

#if ADD(XX,YY)  // Compliant                                        
#endif

This example shows various uses of M in preprocessing directives. The second and third #if clauses check to see if the software defines M before evaluating M. The first #if clause does not check to see if M is defined, and because M is not defined, the statement is noncompliant.

In the final #if clause, the ADD macro resolves to the token XXYY, which is defined. Polyspace® does not report a violation.

Check Information

Group: Preprocessing Directives
Category: Required
AGC Category: Required

Version History

Introduced in R2024a