Main Content

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

C++ macros shall only be used for: include guards, type qualifiers, or storage class specifiers

Description

Rule Definition

C++ macros shall only be used for: include guards, type qualifiers, or storage class specifiers.

Rationale

Aside from defining include guards, type qualifiers, and storage class specifiers, you might use C++ macros for other purposes such as defining constants or function-like macros. These macros do not obey typical linkage and lack scoping mechanism or type safety. Compared to available alternatives in C++, macros are less safe. 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 a macro 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 macros if they are not used for defining include guards, type qualifiers, and storage class specifiers. Instead, use features such as inline function, const or constexpr objects, and function templates.

Polyspace Implementation

The checker flags #define statements where the macros expand to something other than include guards, type qualifiers or storage class specifiers such as static, inline, volatile, auto, register, and const.

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

#ifndef IDENTIFIER //Compliant
#define IDENTIFIER //Compliant
#endif             //Compliant - Include guard

#define STOR extern      // Compliant - Storage class specifier
#define VOL volatile	 //Compliant - Type qualifier

#define CLOCK (xtal/16)              // Noncompliant
#define PLUS2(X) ((X) + 2)           // Noncompliant
#define PI 3.14159F                  // Noncompliant
#define int32_t long                 // Noncompliant
#define STARTIF if(                  // Noncompliant
#define INIT(value) {(value), 0, 0}  // Noncompliant
#define HEADER "filename.h"          // Noncompliant

In this example, Polyspace flags all macros except those that define include guards, storage class specifiers, and type qualifiers.

Check Information

Group: Preprocessing Directives
Category: Required

Version History

Introduced in R2013b