Macros are frequently used to make source code more readable. Macro definitions, regardless of whether they expand to a single or multiple statements, should not conclude with a semicolon. (See PRE10-C. Wrap multistatement macros in a do-while loop.) If required, the semicolon should be included following the macro expansion. Inadvertently inserting a semicolon at the end of the macro definition can unexpectedly change the control flow of the program.
...
This noncompliant code example creates a macro definition for a for
loop in the program. A for
loop should require braces, even if it contains only a single body statement. (See EXP19-C. Use braces for the body of an if, for, or while statement.) This macro takes an integer argument, which is the number of times the loop should run. The programmer has provided inserted a semicolon at the end of the macro definition by mistake.
...
In this noncompliant code example, the programmer defines a macro that increments the value of the first argument, x
, by one 1 and modulates it with the value of the second argument, max
:
Code Block | ||||
---|---|---|---|---|
| ||||
#define INCREMENTINCREMOD(x, max) ((x) = ((x) + 1) % (max)); int index = 0; int value; value = INCREMENTINCREMOD(index, 10) + 2; /* ... */ |
...
Code Block | ||||
---|---|---|---|---|
| ||||
#define INCREMENTINCREMOD(x, max) ((x) = ((x) + 1) % (max)) |
Compliant Solution
This compliant solution uses an inline function as recommended by PRE00-C. Prefer inline or static functions to function-like macros.
Code Block | ||||
---|---|---|---|---|
| ||||
inline int incremod(int *x, int max) {*x = (*x + 1) % max;} |
Risk Assessment
Using a semicolon at the end of a macro definition can result in the change of program control flow and thus unintended program behavior.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
PRE11-C |
Medium |
Probable |
Low | P12 | L1 |
Automated Detection
Tool | Version | Checker | Description |
---|
Astrée |
| macro-final-semicolon | Fully checked | ||||||
Axivion Bauhaus Suite |
| CertC-PRE11 | |||||||
CodeSonar |
| LANG.PREPROC.MACROEND | Macro Does Not End With ) or } | ||||||
Helix QAC |
| C3412 | |||||||
LDRA tool suite |
| 79 S | Enhanced Enforcement | ||||||
PC-lint Plus |
| 823 | Fully supported | ||||||
Polyspace Bug Finder |
| CERT C: Rec. PRE11-C | Checks for macros terminated with semicolons (rule fully covered) | ||||||
RuleChecker |
| macro-final-semicolon | Fully checked |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
SEI CERT C++ |
Coding Standard | VOID PRE11-CPP. Do not conclude macro definitions with a semicolon |
Bibliography
...
...