Home Segments Index Top Previous Next

142: Sidetrip

One common error is to write macros with single-symbol arguments (such as length) in mind, only to use those macros with multiple-symbol expressions. Suppose, for example, that you write the following statement, using the macro defined in Segment 140:

result = square (x + y); 

When expanded, your program works as though you had written the following:

result = x + y * x + y 

Because multiplication has precedence higher than that of addition, you might as well have written x + (y * x) + y, whereas you probably were thinking you would get the effect of writing (x + y) * (x + y).

The solution is to use parentheses routinely and liberally when defining macros. Consider, for example, the following definition of the square macro:

                     *-------- Parentheses added 
                     |      
                     v      
                   ----------- 
#define square (x) ((x) * (x))      /* Better version */ 

Given the new definition, the problem raised in Segment 142 disappears, because the new macro definition leads to the following, parenthesized expansion:

result = ((x + y) * (x + y)); 

Note, however, that the definition of square as a macro leads to the calculation of x + y twice. If you were to implement square as a function, x + y would be computed only once, as the argument is evaluated, but then your program would be doing a run-time function call. Thus, the use of macros can involve complex performance tradeoffs.