奇怪的 C++预处理器宏语法

发布于 2024-09-12 12:39:08 字数 850 浏览 5 评论 0原文

我已经将我的问题归结为这个代码片段 - 但它是一个更大程序的一部分,所以我不想用不同的方式来做到这一点 - 我需要一种方法来使这个工作!

当我从这段代码生成一个预处理文件时:

#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
}

我得到:

enum foo {
    xyz
}; // line 108

int __stdcall wWinMain(...)
{
    foo bar = xyz; // line 112
}

这就是我想要的。但是,如果我尝试编译代码,我会得到:

错误 C2146:语法错误:标识符“z”第 108 行之前缺少“}”
错误 C2143:语法错误:缺少 ';'在“}”第 108 行之前
错误 C2143:语法错误:缺少 ';'在“}”第 108 行之前
错误 C2059:语法错误:“}”第 108 行
错误 C2065:'xyz':未声明的标识符第 112 行

我无法解决!这个问题似乎是由 ## 引起的:

#define OUTER(a, b) \
    a##b

但为什么(以及如何解决它)超出了我的范围......

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...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

守护在此方 2024-09-19 12:39:33

如果您使用 gcc,则可以为其指定 -E 选项以查看预处理的输出。然后您可以轻松查看预处理器的输出以及如何进一步调试宏。其他编译器也有类似的选项。

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.

日记撕了你也走了 2024-09-19 12:39:30

使用 gcc 预处理您的示例结果:

enum foo {
t.c:7:1: error: pasting ")" and "z" does not give a valid preprocessing token
    xy z
};

这应该可以让您了解为什么 Luther 的解决方案有效而您的解决方案无效。

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.

一桥轻雨一伞开 2024-09-19 12:39:25

使用这个代替:

#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
}

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文