I've distilled my problem down to this code snippet - but it is a part of a larger program so I don't want a different way to do this - I need a way to make this work!
When I generate a preprocessed file from this code:
#define OUTER(a, b) \
a##b
#define INNER(c, d) \
c##d
enum foo {
OUTER(INNER(x, y), z)
}; // line 108
int APIENTRY _tWinMain(...)
{
foo bar = xyz; // line 112
}
I get:
enum foo {
xyz
}; // line 108
int __stdcall wWinMain(...)
{
foo bar = xyz; // line 112
}
which is what I want. However, if I try to compile the code I get:
error 开发者_运维知识库C2146: syntax error : missing '}' before identifier 'z' line 108
error C2143: syntax error : missing ';' before '}' line 108 error C2143: syntax error : missing ';' before '}' line 108 error C2059: syntax error : '}' line 108 error C2065: 'xyz' : undeclared identifier line 112
I can't work it out! The problem seems to be caused by the ##
in the:
#define OUTER(a, b) \
a##b
but why (and how to fix it) is beyond me...
Use this instead:
#define CONCAT(X,Y) X##Y
#define OUTER(a, b) CONCAT(a,b)
#define INNER(a, b) CONCAT(a,b)
enum foo {
OUTER(INNER(x, y),z)
}; // line 108
int main(...)
{
foo bar = xyz; // line 112
}
Preprocessing your example with gcc
results in:
enum foo {
t.c:7:1: error: pasting ")" and "z" does not give a valid preprocessing token
xy z
};
which should give you a clue of why Luther's solution works and yours doesn't.
If you are using gcc, then you can give it the -E option to see the preprocessed output. Then you can easily see what the preprocessor has output and how to further debug your macros. Other compilers also have similar options.
精彩评论