Main Content

CERT C: Rec. PRE10-C

Wrap multistatement macros in a do-while loop

Since R2020a

Description

Rule Definition

Wrap multistatement macros in a do-while loop.1

Polyspace Implementation

The rule checker checks for Macro with multiple statements.

Examples

expand all

Issue

Macro with multiple statements occurs when a macro contains multiple semicolon-terminated statements, irrespective of whether the statements are enclosed in braces.

Risk

The macro expansion, in certain contexts such as an if condition or a loop, can lead to unintended program logic.

For instance, consider the macro:

#define RESET(x,y) \
   x=0; \
   y=0;
In an if statement such as:
if(checkSomeCondition)
   RESET(x,y);
the macro expands to:
if(checkSomething)
   x=0;
y=0;
which might be unexpected if you want both statements to be executed in an if block.

Fix

In a macro definition, wrap multiple statements in a do...while(0) loop.

For instance, in the preceding example, use the definition:

#define RESET(x,y) \
   do { \
     x=0; \
     y=0; \
   } while(0)
This macro is appropriate to expand in all contexts. The while(0) ensures that the statements are executed only once.

Alternatively, use inline functions in preference to function-like macros that involve multiple statements.

Note that the loop is required for the correct solution and wrapping the statements in braces alone does not fix the issue. The macro expansion can still lead to unintended code.

Example – Macro with Multiple Statements
#define RESET(x,y) \ //Noncompliant
   x=0; \
   y=0;

void func(int *x, int *y, int resetFlag){
    if(resetFlag)
        RESET(x,y);    
}

In this example, the defect occurs because the macro RESET consists of multiple statements.

Correction – Wrap Multiple Statements of Macro in do-while Loop

Wrap the statements of the macro in a do..while(0) loop in the macro definition.

#define RESET(x,y) \
   do { \
     x=0; \
     y=0; \
   } while(0)

void func(int *x, int *y, int resetFlag){
    if(resetFlag)
        RESET(x,y);    
}

Check Information

Group: Rec. 01. Preprocessor (PRE)

Version History

Introduced in R2020a


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.