Delaying macro expansion
Consider this code:
#define N_ 0
#define N_X 1
#define M(a) N_
M(arg)X; // #1 -- I'd like this to expand to N_X, and ultimately 1; but it's 0X instead
M(arg); // #2 -- this should and does expand to 0
The problem with #1 is that after expanding M(), the result contains N_, and before concatenating it with X, the preprocessor finds and expands it. Can I somehow delay this re-scanning of the re开发者_StackOverflow社区sult for further macros, such that the preprocessor finds N_X instead of N_?
First there is a different between N_ X
and N_X
. The first are two tokens. To form one token you have to use the token pasting operator ##
, but this operator inhibits macro expansion, so this:
M(a) ## X //Compiler error can't paste ')' and X
Causes a compile error, because its trying to paste M(a)
and not N_
. You can allow for macros to expand before pasting by using an extra level of macros(this is really commonly used macro):
#define PRIMITIVE_CAT(x, y) x ## y
#define CAT(x, y) PRIMITIVE_CAT(x, y)
However, in your case, this still won't work:
CAT(M(a), X) //expands to 0
That is because, you are using object macros, rather than function macros. If you change it to function macros, it will work how you want:
#define N_() 0
#define N_X() 1
#define M(a) N_
CAT(M(arg), X)() // expands to 1
M(arg)() // expands to 0
Function macros are more powerful and you can delay the expansion of them. Here's how you can delay them for one scan:
#define EMPTY()
#define DEFER(x) x EMPTY()
N_() //Expands to 0
DEFER(N_)() //Expands N_ ()
Delaying macro expansion like this is one of the ways recursion can be implemented in the preprocessor.
No. The preprocessor works line by line and performs no recursion or backtracking whatsoever. It reads a line, process a special #
line or substitute something, and goes to the next line. This also means it doesn't make any substitutions before a #define
nor after an #undef
. You'll have to work around the issue.
精彩评论