[Contents]   [Back]   [Prev]   [Up]   [Next]   [Forward]  

Separate Expansion of Macro Arguments

We have explained that the expansion of a macro, including the substituted actual arguments, is scanned over again for macro calls to be expanded.

What really happens is more subtle: first each actual argument text is scanned separately for macro calls. Then the results of this are substituted into the macro body to produce the macro expansion, and the macro expansion is scanned again for macros to expand.

The result is that the actual arguments are scanned twice to expand macro calls in them.

Most of the time, this has no effect. If the actual argument contained any macro calls, they are expanded during the first scan. The result therefore contains no macro calls, so the second scan does not change it. If the actual argument were substituted as given, with no prescan, the single remaining scan would find the same macro calls and produce the same results.

You might expect the double scan to change the results when a self-referential macro is used in an actual argument of another macro (see section Self-Referential Macros): the self-referential macro would be expanded once in the first scan, and a second time in the second scan. But this is not what happens. The self-references that do not expand in the first scan are marked so that they will not expand in the second scan either.

The prescan is not done when an argument is stringified or concatenated. Thus,

#define str(s) #s
#define foo 4
str (foo)

expands to `"foo"'. Once more, prescan has been prevented from having any noticeable effect.

More precisely, stringification and concatenation use the argument as written, in un-prescanned form. The same actual argument would be used in prescanned form if it is substituted elsewhere without stringification or concatenation.

#define str(s) #s lose(s)
#define foo 4
str (foo)

expands to `"foo" lose(4)'.

You might now ask, "Why mention the prescan, if it makes no difference? And why not skip it and make the preprocessor faster?" The answer is that the prescan does make a difference in three special cases:

We say that nested calls to a macro occur when a macro's actual argument contains a call to that very macro. For example, if `f' is a macro that expects one argument, `f (f (1))' is a nested pair of calls to `f'. The desired expansion is made by expanding `f (1)' and substituting that into the definition of `f'. The prescan causes the expected result to happen. Without the prescan, `f (1)' itself would be substituted as an actual argument, and the inner use of `f' would appear during the main scan as an indirect self-reference and would not be expanded. Here, the prescan cancels an undesirable side effect (in the medical, not computational, sense of the term) of the special rule for self-referential macros.

But prescan causes trouble in certain other cases of nested macro calls. Here is an example:

#define foo  a,b
#define bar(x) lose(x)
#define lose(x) (1 + (x))


We would like `bar(foo)' to turn into `(1 + (foo))', which would then turn into `(1 + (a,b))'. But instead, `bar(foo)' expands into `lose(a,b)', and you get an error because lose requires a single argument. In this case, the problem is easily solved by the same parentheses that ought to be used to prevent misnesting of arithmetic operations:

#define foo (a,b)
#define bar(x) lose((x))

The problem is more serious when the operands of the macro are not expressions; for example, when they are statements. Then parentheses are unacceptable because they would make for invalid C code:

#define foo { int a, b; ... }

In GNU C you can shield the commas using the `({...})' construct which turns a compound statement into an expression:

#define foo ({ int a, b; ... })

Or you can rewrite the macro definition to avoid such commas:

#define foo { int a; int b; ... }

There is also one case where prescan is useful. It is possible to use prescan to expand an argument and then stringify it--if you use two levels of macros. Let's add a new macro `xstr' to the example shown above:

#define xstr(s) str(s)
#define str(s) #s
#define foo 4
xstr (foo)

This expands into `"4"', not `"foo"'. The reason for the difference is that the argument of `xstr' is expanded at prescan (because `xstr' does not specify stringification or concatenation of the argument). The result of prescan then forms the actual argument for `str'. `str' uses its argument without prescan because it performs stringification; but it cannot prevent or undo the prescanning already done by `xstr'.

[Contents]   [Back]   [Prev]   [Up]   [Next]   [Forward]