开发者

Weird C++ preprocessor macro syntax

开发者 https://www.devze.com 2023-01-09 14:27 出处:网络
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!

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号