Why are argument substitutions not replaced during rescanning?

Posted by James McNellis on Stack Overflow See other posts from Stack Overflow or by James McNellis
Published on 2010-06-01T12:07:26Z Indexed on 2010/06/01 12:23 UTC
Read the original article Hit count: 200

Filed under:
|
|

Consider the following macro definitions and invocation:

#define x x[0]
#define y(arg) arg

y(x)

This invocation expands to x[0] (tested on Visual C++ 2010, g++ 4.1, mcpp 2.7.2, and Wave).

Why? Specifically, why does it not expand to x[0][0]?

During macro replacement,

A parameter in the replacement list...is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced (C++03 §16.3.1/1).

Evaluating the macro invocation, we take the following steps:

  • The function-like macro y is invoked with x as the argument for its arg parameter
  • The x in the argument is macro-replaced to become x[0]
  • The arg in the replacement list is replaced by the macro-replaced value of the argument, x[0]

The replacement list after substitution of all the parameters is x[0].

After all parameters in the replacement list have been substituted, the resulting preprocessing token sequence is rescanned...for more macro names to replace (C++03 §16.3.4/1).

If the name of the macro being replaced is found during this scan of the replacement list...it is not replaced. Further, if any nested replacements encounter the name of the macro being replaced, it is not replaced (C++03 §16.3.4/2).

The replacement list x[0] is rescanned (note that the name of the macro being replaced is y):

  • x is identified as an object-like macro invocation
  • x is replaced by x[0]

Replacement stops at this point because of the rule in §16.3.4/2 preventing recursion. The replacement list after rescanning is x[0][0].

I have clearly misinterpreted something since all of the preprocessors I've tested say I am wrong. In addition, this example is a piece of a larger example in the C++0x FCD (at §16.3.5/5) and it too says that the expected replacement is x[0].

Why is x not replaced during rescanning?

C99 and C++0x effectively have the same wording as C++03 in the quoted sections.

© Stack Overflow or respective owner

Related posts about c++

Related posts about c