...
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]\]). |
...