Start here

Home
About Klocwork
What's new
Fixed issues
Release notes
Installation

Reference

C/C++ checkers
Java checkers
C# checkers
MISRA C 2004 checkers
MISRA C++ 2008 checkers
MISRA C 2012 checkers
MISRA C 2012 checkers with Amendment 1
Commands
Metrics
Troubleshooting
Reference

Product components

C/C++ Integration build analysis
Java Integration build analysis
Desktop analysis
Refactoring
Klocwork Static Code Analysis
Klocwork Code Review
Structure101
Tuning
Custom checkers

Coding environments

Visual Studio
Eclipse for C/C++
Eclipse for Java
IntelliJ IDEA
Other

Administration

Project configuration
Build configuration
Administration
Analysis performance
Server performance
Security/permissions
Licensing
Klocwork Static Code Analysis Web API
Klocwork Code Review Web API

Community

View help online
Visit RogueWave.com
Klocwork Support
Rogue Wave Videos

Legal

Legal information

MISRA.ELIF.UNDEF

Undefined macros in #elif 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 evaluation

Category: Required

Analysis: Decidable, Single Translation Unit

Applies to: C90, C99

Amplification

As well as using a #define preprocessor directive, identifiers may effectively be #define’d in other, implementation-defined, ways. For example some implementations support:
  • Using a compiler command-line option, such as -D to allow identifiers to be defined prior to translation;
  • Using environment variables to achieve the same effect;
  • Pre-defined identifiers provided by the compiler.

Rationale

If 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.

Example

The 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 #elif directive.

This rule is also covered by MISRA.IF.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.IF.UNDEF.

Rationale

If 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.