Search code examples
cmacrospreprocessor

Preprocessor macro expansion (ISO/IEC 9899:1999 (E) §6.10.3.5 EXAMPLE 3)


In the C99 standard, example 3 of section 10.3.5 demonstrates macro expansion for f (modified):

#define f(a)    f(a)
#define z       z[0]
f(z)

The result of expansion is "f(z[0])", which is true also for MSVC and GCC. But I can't figure out why the result is not "f(z[0][0])" as might result from the following sequence of macro expansions:

  • during arguments macro expansion, z argument is replaced with z[0]:
    f(z[0])
  • "f(z[0])" is replaced with "f(z[0])":
    f(z[0])
  • during rescan, z is replaced with z[0] again:
    f(z[0][0])

which obviously differs from the correct result. Both expansions of z are completely separate, so no recursion prevention applies. However, one of z expansions is not performed. Why?

Please help me understand where I'm wrong here

Obviously, all preprocessors produce the correct result, so it's important for me to understand what's really going on here.


Solution

  • I can see where your confusion comes from. This is not an official source from the standard, but it is from GCC and should be authorative enough to explain what is happening. It has a paragraph that exactly refers to your case here.

    You might expect the double scan to change the results when a self-referential macro is used in an argument of another macro (see Self-Referential Macros): the self-referential macro would be expanded once in the first scan, and a second time in the second scan. However, 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.

    At the time of writing, this is the third paragraph from https://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html