Main Content

MISRA C++:2023 Rule 19.3.4

Parentheses shall be used to ensure macro arguments are expanded appropriately

Since R2024b

Description

Rule Definition

Parentheses shall be used to ensure macro arguments are expanded appropriately.

Rationale

Macro expansion results in textual replacement where the preprocessor replaces a code snipped directly into your code before compilation. This direct text replacement can result in unexpected behavior if the arguments are expressions due to operator precedence.

If you are not using a macro parameter as an expression, then the parentheses are not necessary because no operators are involved in the macro.

Polyspace Implementation

Polyspace® reports this rule violation whenever a macro parameter argument is an expression that contains an operator or operand and is not enclosed in parentheses. Violations are not reported if you use an unparenthesized array element as a macro parameters.

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

#define mac1(x, y) (x * y)
#define mac2(x, y) ((x) * (y))

void foo(void){
    int r;

    r = mac1(1 + 2, 3 + 4);       // Noncompliant
    r = mac1((1 + 2), (3 + 4));   // Compliant

    r = mac2(1 + 2, 3 + 4);       // Compliant
}

In this example, mac1 and mac2 are two defined macro expressions. The definition of mac1 does not enclose the arguments in parentheses. In line 7, the macro expands to r = (1 + 2 * 3 + 4); This expression can be (1 + (2 * 3) + 4) or (1 + 2) * (3 + 4). However, without parentheses, the program does not know the intended expression. Line 8 uses parentheses, so the line expands to (1 + 2) * (3 + 4). This macro expression is compliant.

The definition of mac2 does enclose the argument in parentheses. Line 10 (the same macro arguments in line 7) expands to (1 + 2) * (3 + 4). This macro and macro expression are compliant.

Check Information

Group: Preprocessing Directives
Category: Required

Version History

Introduced in R2024b