Reputation: 1972
I have difficulty understanding how rewriting rules are applied by the C preprocessor in the following context. I have the following macros:
#define _A(x) "A" _##x
#define _B(x) "B" _##x
#define X(x) _##x
The idea is that each of these macros uses the concatenation to create a new expression, which can itself be a macro — if its a macro, I'd like it to be expanded:
Now, the following expands just like I expect:
X(x) expands to _x
X(A(x)) expands to "A" _x
X(A(B(x))) expands to "A" "B" _x
However, once the same macro is used more then once, the expansion stops:
X(A(A(x))) expands to "A" _A(x), expected "A" "A" _x
X(B(B(x))) expands to "B" _B(x), expected "B" "B" _x
X(A(B(A(x)))) expands to "A" "B" _A(x), expected "A" "B" "A" _x
X(A(B(A(B(x))))) expands to "A" "B" _A(B(x)), expected "A" "B" "A" "B" _x
I guess that there is some sort of "can expand same-named macro only once" rule at play here? Is there something I can do to get the macros to expand the way I want?
Upvotes: 4
Views: 9389
Reputation: 4515
When I want to work out macro expansion I generally use this diagram, which I constructed using section 6.10.3 from standard. Hope it helps...
As Toby has already mentioned, nested macros will not be expanded recursively.
Upvotes: 5
Reputation: 30709
C99 draft says that there's no recursion permitted in macro expansion:
6.10.3.4 Rescanning and further replacement
- After all parameters in the replacement list have been substituted and
#
and##
processing has taken place, all placemarker preprocessing tokens are removed. The resulting preprocessing token sequence is then rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace.- 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 X(A(A(x)))
expands to "A" _A(x)
, but that expansion is not itself expanded, as you've seen.
Upvotes: 3