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-C), occasionally they are not feasible (when macros are expected to operate on variables of different types, for example).
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 |
medium |
probable |
low |
P12 |
L1 |
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
\[[ISO/IEC PDTR 24772|AA. C References#ISO/IEC PDTR 24772]\] "NMP Pre-processor Directions" |