【问题标题】:Function-like macro expands to nothing类函数宏扩展为空
【发布时间】:2020-11-12 09:57:49
【问题描述】:

这是一个很奇怪的问题。这是一个看起来非常简单的函数式宏,我已经多次看到它的示例。我什至以前用过!但是,我只是在 6 小时后无法正常工作。我累了,决定在这里问。也许有人发现了问题。最小的可重现情况是:

enum e {
    x, y, z,

#define Func(X, Y, Z) \
  my_##X = Y

Func(x, y, z),
};

used in clang 源代码的方式类似。我也包含一个包含宏定义和使用的文件。

编辑:

非常感谢您的回答和 cmets。我确实使用过 Godbolt,但是在我的构建失败之后。事实证明,宏在我的构建过程中从未失败过。那是因为我没有使用宏!它没有被使用,所以它从来没有产生过输出。这是相当可耻的。我必须接受我的错误,然后继续前进。我必须通过本地预处理来检查它。在 Godbolt 中获取空字符串让我相信我做错了什么。

【问题讨论】:

  • 为什么我们必须在枚举中使用这么奇怪的函数?
  • 它应该如何工作以及它是如何工作的?
  • 它扩展到my_x = y...这不是你想要的吗?
  • @ForceBru 我在我的计算机上使用 gcc 和 clang 预处理器进行了测试。在那里工作正常。您的godbolt示例也缺少许多其他行;可能是其花哨的输出渲染有些奇怪。
  • @Shawn,确实,取消选择“未使用的标签”会显示正确的输出。也许 OP 也在 Godbolt 中运行它

标签: c++ c c-preprocessor


【解决方案1】:

显然(如 cmets 中的 @Shawn 所述)这是因为检查了 Godbolt“未使用标签”(“漏斗”过滤器图标)中的编译器输出,如果您使用预处理器输出 -E 运行,它将过滤掉不用的东西。

您可以通过在编译程序中的某处简单地引用my_x 来解决此问题,或者在查看预处理器输出时简单地取消选中 Godbolt 中的“未使用标签”。

作为旁注,请注意枚举末尾的“尾随逗号”是在 C99 中添加的,因此如果您使用较旧的 C90 编译器,您可能会因此遇到奇怪的编译器故障。

【讨论】:

  • 对不起,原来是我的错;我定义了宏,但从未在我的原始代码中使用它。我在 C++17 中使用它,所以没关系。
【解决方案2】:

根据Godbolt open issue (feature request) 1380,Godbolt 不(还)支持-E 选项[强调我的]:

以某种方式支持 -E 输出 #1380

[...]

apmorton 于 2019 年 5 月 15 日发表评论

似乎是标签和指令的组合造成的 过滤。

[...]

您可能应该关闭任何用于解析的过滤器 当您指示编译器输出某些内容时的程序集 除了组装。

不确定这是否真的是过滤器中的错误,因为它们是 从技术上讲,他们应该做的 - 只是 他们是 在他们不应该的输出上运行。

也许它可以检测到 -E 的使用并禁用过滤器 汇编输出?

partouf 于 2019 年 5 月 18 日发表评论

程序集解析器并不是真的要支持 -E,它需要的是 asm 而不是 C++,所以真的没有错。

我们可以考虑在 -E 上禁用解析器,但我们需要在每个编译器的基础上进行检测。

因此,OP 提到的问题以及 @Jabberwocky in a comment 显示的 more minimal example 都在实际编译时产生预期的程序,但在使用 -E 选项时不会产生预期的预处理器输出(除了预处理)。

【讨论】:

  • 我犯了一个错误,这个 Godbolt 问题给我带来了压力。
【解决方案3】:

我敢打赌这是 Godbolt 中的换行问题。解决方法:

#define Func(X, Y, Z) ,my_ ## X = Y


enum e {
    x, y, z

    Func(x, y, z),
};

https://godbolt.org/z/Mznf5o

【讨论】:

  • 我可以在这里复制这个:godbolt.org/z/94onTh。情况就更简单了。你能解释一下 Godbolt 中的这个换行问题是什么吗? Func 按预期扩展,但 Func2 没有。如果添加int bar1;,它也会扩展。
  • 我知道该链接,但它没有解释 换行问题
  • 是的,这是一个新行问题:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-25
  • 1970-01-01
  • 2019-11-16
  • 1970-01-01
  • 1970-01-01
  • 2016-02-28
  • 2016-01-14
相关资源
最近更新 更多