...
Code Block | ||
---|---|---|
| ||
#define CUBE(X) ((X) * (X) * (X)) int i = 3; int a = 81 / CUBE(i); |
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'Unexpected behavior resulting from macro expansion is not limited to function-like macros. The object-like macro definition in this example is non-compliant because its replacement list is not parenthesized.
Code Block | ||
---|---|---|
| ||
#define sum a+bEOF -1 /* ... */ int result = sum*4; |
The value of result
is a+(b*4)
instead of the expected (a+b)*4
.
Compliant Solution
if (c EOF) {
/* ... */
}
|
Wiki Markup |
---|
In this example, the programmer has mistakenly omitted the comparison operator (see \[[MSC02-A. Avoid 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 operatorParenthesizing the macro replacement list yields the expected answer.
Code Block | ||
---|---|---|
| ||
#define sumEOF (a+b-1) /* ... */ intif result(c != sum*4; EOF) { /* ... */ } |
Note that there must be a space after sum
EOF
, otherwise it becomes a function-like macro (and one that is incorrectly formed since -1 cannot be a formal parameter).
Exceptions
PRE02-EX1. A macro that expands to a single identifier or function call is not affected by the precedence of any operators in the surrounding expression, so its replacement list need not be parenthesized.
...
Wiki Markup |
---|
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.10, "Preprocessing directives," and Section 5.1.1, "Translation environment"
\[[Plum 85|AA. C References#Plum 85]\] Rule 1-1
\[[Summit 05|AA. C References#Summit 05]\] Question 10.1 |