Macros are often used to execute a sequence of multiple statements as a group.
While inline functions are, in general, more suitable for this task (see PRE00-A. Prefer inline or static functions to function-like macros), occasionally they are not feasible. For instance, the macros are expected to operate on variables of different types; this is well-handled by macros, but not by inline functions.
When multiple statements are used in a macro, they should be bound together in a loop syntactically, so the macro can appear safely inside if-clauses, or other places that expect a single statement or a statement block.
| /* Swaps two values, requires tmp variable to be defined */ #define SWAP(x,y) \ tmp = x; \ x = y; \ y = tmp | 
This macro will expand correctly in a normal sequence of statements, but not as the then-clause in an if statement:
| int x, y, z, tmp; if (z == 0) SWAP( x, y); | 
This will expand to:
| int x, y, z, tmp; if (z == 0) tmp = x; x = y; y = tmp; | 
which is certainly not what the author intended.
Wrapping the macro inside a do-while loop mitigates the problem.
| 
/* Swaps two values, requires tmp variable to be defined */
#define SWAP(x,y) \
  do { \
    tmp = x; \
    x = y; \
    y = tmp; \
  while (0)
 | 
The do-while loop will always be executed exactly once.
Improperly sealed statement macros will cause behavior that is unexpected and difficult to diagnose.
| Rule | Severity | Likelihood | Remediation Cost | Priority | Level | 
|---|---|---|---|---|---|
| PRE10-A | high | high | low | P9 | L2 | 
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
PRE09-A. Do not replace secure functions with less secure functions      01. Preprocessor (PRE)