You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

The macro expansion must always be parenthesized to protect any lower-precedence operators from the surrounding expression.

Non-Compliant Code Example

This PRODUCT() macro definition is non-compliant because it fails to parethesize the macro expansion.

#define PRODUCT(A,B) (A) * (B)
int n, m;
int a = 1 / PRODUCT(n, m)

As a result, the invocation

1 / PRODUCT(n, m)

expands to

1 / n * m

(which evaluates as (1 / n) * m), while the desired behavior is clearly

1 / (n * m)

See also PRE01.

Compliant Solution

By adding parentheses around each argument, this definition of the PRODUCT() macro expands correctly.

#define PRODUCT(A,B) ( (A) * (B) )
int n, m;
int a = 1 / PRODUCT(n, m)

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 PRODUCT() macro above, the invocation:

PRODUCT(i+, i+);

would expand to

i++ * i++

which is undefined. This is less obvious in the case of the CUBE() macro below:

#define CUBE(X, Y, Z) ( (X) * (Y) * (Z))
int i = 3;
int a = CUBE(i++);

The CUBE() macro in this expression expands to:

int a = i++ * i++ * i++;

Which is still undefined.

References

comp.lang.c FAQ list - Question 10.1

  • No labels