Use parentheses around any macro replacement list that contains operators.
Non-Compliant Coding Example
In this non-compliant coding example, EOF
is defined as -1
. The macro replacement list consists of a unary negation operator '-' followed by an integer literal '1'.
Code Block | ||
---|---|---|
| ||
#define EOF -1
/* ... */
if (c EOF) {
/* ... */
}
|
Wiki Markup |
---|
InThis this example, the programmer content has mistakenlybeen omittedmoved the comparison operator (see to \[[MSC02PRE02-A. AvoidMacro errors of omission]\]) from the conditional statement, which should be {{c \!= EOF}}. After macro expansion, the conditional expression is incorrectly evaluated as a binary operation: {{c-1}}. This is syntactically correct, even though it is certainly not what the programmer intended. |
Parenthesizing the -1
in the declaration of EOF
ensures that the macro expansion is evaluated correctly.
Code Block |
---|
#define EOF (-1)
|
Once this modification is made, the non-compliant code example no longer compiles as the macro expansion results in the conditional expression c (-1)
, which is no longer syntactically valid.
Compliant Solution
The following compliant solution uses parentheses around the macro replacement list and adds the (previously omitted) comparison operator.
Code Block | ||
---|---|---|
| ||
#define EOF (-1)
/* ... */
if (c != EOF) {
/* ... */
}
|
Risk Assessment
Failure to use parentheses around macro replacement lists that contain operators can result in unintended program behavior.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
PRE05-A | 1 (low) | 1 (unlikely) | 2 (medium) | P2 | L3 |
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
Wiki Markup |
---|
\[[Plum 85|AA. C References#Plum 85]\] Rule 1-1 \[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.10, "Preprocessing directives," and Section 5.1.1, "Translation environment"replacement lists should be parenthesized]\]. |