MISRA.IF.UNDEFUndefined macros in #if directive.
MISRA C 2012 Rule 20.9: All identifiers used in the controlling expression of #if or #elif preprocessing directives shall be #define ’d before evaluationCategory: Required Analysis: Decidable, Single Translation Unit Applies to: C90, C99 AmplificationAs well as using a #define preprocessor directive, identifiers may effectively be #define’d in other, implementation-defined, ways. For example some implementations support:
RationaleIf an attempt is made to use a macro identifier in a preprocessor directive, and that identifier has not been defined, then the preprocessor will assume that it has a value of zero. This may not meet developer expectations. ExampleThe following examples assume that the macro M is undefined. #if M == 0 /* Non-compliant */ /* Does 'M' expand to zero or is it undefined? */ #endif #if defined ( M ) /* Compliant - M is not evaluated */ #if M == 0 /* Compliant - M is known to be defined */ /* 'M' must expand to zero. */ #endif #endif /* Compliant - B is only evaluated in ( B == 0 ) if it is defined */ #if defined ( B ) && ( B == 0 ) #endif MISRA-C 2004 Rule 19.11 (required): All macro identifiers in preprocessor directives shall be defined before use, except in #ifdef and #ifndef preprocessor directives and the defined() operator.Undefined macros in #if directive. This rule is also covered by MISRA.ELIF.UNDEF. If an attempt is made to use an identifier in a preprocessor directive, and that identifier has not been defined, the preprocessor will sometimes not give any warning but will assume the value zero. #ifdef, #ifndef and defined() are provided to test the existence of a macro, and are therefore excluded. Example#if x < 0 /* x assumed to be zero if not defined */ Consideration should be given to the use of a #ifdef test before an identifier is used. Note that preprocessing identifiers may be defined either by use of #define directives or by options specified at compiler invocation. However the use of the #define directive is preferred. MISRA-C++ 2008 Rule 16-0-7 (required): Undefined macro identifiers shall not be used in #if or #elif preprocessor directives, except as operands to the defined operator.This rule is also covered by MISRA.ELIF.UNDEF. RationaleIf an attempt is made to use an identifier in a preprocessor directive, and that identifier has not been defined, the preprocessor will assume the value zero. #ifdef, #ifndef and defined() are provided to test the existence of a macro, and are therefore excluded. Example#if x < 0 // Non-compliant - x assumed to be zero as it is not defined Consideration should be given to the use of a #ifdef test before an identifier is used. Note that preprocessing identifiers may be defined either by use of #define directives or by options specified at compiler invocation. However, the use of the #define directive is preferred. |