...
This CUBE()
macro definition is non-compliant because it fails to parenthesize the variable names.
Code Block | ||
---|---|---|
| ||
#define CUBE(I) (I * I * I) int a = 81 / CUBE(2 + 1); |
As a result, the invocation
Code Block | ||
---|---|---|
| ||
int a = 81 / CUBE(2 + 1); |
expands to
Code Block | ||
---|---|---|
| ||
int a = 81 / (2 + 1 * 2 + 1 * 2 + 1); /* evaluates to 11 */ |
while the desired behavior is
Code Block | ||
---|---|---|
| ||
int a = 81 / ( (2 + 1) * (2 + 1) * (2 + 1)); /* evaluates to 3 */ |
...
Parenthesizing all variable names in the CUBE()
macro allows it to expand correctly (when invoked in this manner).
Code Block | ||
---|---|---|
| ||
#define CUBE(I) ( (I) * (I) * (I) ) int a = 81 / CUBE(2 + 1); |
However, if a parameter appears several times in the expansion, the macro may not work properly if the actual argument is an expression with side effects. Given the CUBE()
macro above, the invocation
Code Block | ||
---|---|---|
| ||
int a = 81 / CUBE(i++); |
expands to
Code Block |
---|
int
...
a
...
=
...
81
...
/
...
(i++
...
*
...
i++
...
*
...
i++);
Code Block | ||||
---|---|---|---|---|
|
||||
Wiki Markup |
---|
which is undefined (see \[[EXP30|EXP30-C. Do not depend on order of evaluation between sequence points]\]). |
...