Main Content

MISRA C++:2008 Rule 16-2-1

The preprocessor shall only be used for file inclusion and include guards

Description

Rule Definition

The preprocessor shall only be used for file inclusion and include guards.

Rationale

Aside from inclusion and include guarding, you might use preprocessor directives for other purposes such as defining constants or function-like macros. These preprocessor directives do not obey typical linkage and lack scoping mechanism or type safety. Preprocessor directives are less safe as compared to equivalent C++ features. For instance, a constant defined by using a #define statement retains its value across all scopes even if it is defined in a local scope. Using the #define preprocessor instead of a constexpr might lead to confusion if you define a constant differently in different scopes. Because a constexpr variable maintains a well defined scope, it is a safer alternative. The constexpr is efficient because it is a compile time constant.

Avoid preprocessor directives if they are not used for inclusion or include guards. Instead, use features such as inline functions, const or constexpr objects, and templates.

Polyspace Implementation

Polyspace® raises a violation of this rule in an included header file when either of these conditions is true:

  • #define is used outside of an include guard. These #define statements typically define constants and function-like macros.

  • #ifndef is used outside of an include guard.

Polyspace considers this idiom as the correct include guard idiom:

#ifndef <identifier>
#define <identifier>
#endif

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

file1.hmain.cpp

#ifndef MY_FILE
#define MY_FILE //Compliant
#endif
#define PI 3.1416 //Noncompliant
constexpr double pi = 3.1416;

#include"file1.h"
//...

In this example, include file file1.h contains two #define statements. The first #define directive is used within an include guard. This directive is compliant with this rule. The second #define directive defines the constant macro PI. This directive is noncompliant with this rule and Polyspace flags it. A better alternative is to use a constexpr variable.

Check Information

Group: Preprocessing Directives
Category: Required

Version History

Introduced in R2013b