Why is the macro-name not painted blue?

Viewed 194

Say I have the following two macro definitions:

#define foo(X) 1 bar
#define bar(X) 2 foo

Why does foo(X)(Y)(Z) expand to 1 2 1 bar?

According to the C99 standard 6.10.3.4 Rescanning and further replacement

If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file’s preprocessing tokens), it is not replaced. Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced. These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.

So the way these tokens seems to be translated is the following sequence

foo(X)(Y)(Z)
1 bar(Y)(Z)
1 2 foo(Z)
1 2 1 bar

So apparently the second macro invocation of foo doesn't get painted blue. I am somewhat unsure why this is actually the case. Isn't it part of the replacement caused by the invocation of bar which would make it a nested replacement of the replacement of the first invocation of foo.

I can only argue that the way these expansions work is that the tokens that cause the macro invocations of both foo and bar are partially in the nested replacement, i.e. the name of the macro is inside it and partially outside of the replacement, i.e. the parenthesis part is outside the replacement.

Or perhaps I am completely misunderstanding the meaning of nested replacement.

Can somebody be so kind to clarify this.

1 Answers

There are 2 replacement stages here. First happens during argument substitution, which happens in isolation from rest of the file:

6.10.3.1 Argument substitution

  1. After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), 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 as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.

Second stage, rescanning, happens after macro and it's arguments have been expanded:

6.10.3.4 Rescanning and further replacement

  1. After all parameters in the replacement list have been substituted and # and ## processing has taken place, all placemarker preprocessing tokens are removed. Then, the resulting preprocessing token sequence is rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace.

Paragraph you are referring to applies only to the first stage, argument substitution:

  1. If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file’s preprocessing tokens), it is not replaced. ...

Since your macros foo and bar don't use their arguments, you are only seeing effects of the rescanning phase.

Related