【问题标题】:Preprocessor token expansion [duplicate]预处理器令牌扩展[重复]
【发布时间】:2011-05-16 03:29:06
【问题描述】:

我对预处理器如何工作的心智模型显然不完整,这让我发疯。

我想连接两个标记,但第二个标记应该先展开。

#define ANSWER 42

#define FOO foo_ ## ANSWER

在这里,FOO 扩展为 foo_ANSWER,但我希望它是 foo_42。所以我定义了一个MERGE 宏,希望这会在连接之前以某种方式扩展参数:

#define MERGE(x, y) x ## y

#define BAR MERGE(bar_, ANSWER)

BAR 仍扩展为bar_ANSWER 而不是bar_42。所以我定义了另一个宏HELPER

#define HELPER(x, y) MERGE(x, y)

#define BAZ HELPER(baz_, ANSWER)

现在BAZ 已成功扩展为baz_42。目前,这对我来说似乎很神奇。

谁能向我解释这种行为?扩展规则究竟是如何工作的?

【问题讨论】:

  • 很抱歉,我也对同一问题提出了可能重复的问题。我想知道为什么没有清楚地记录这种行为。我的意思是预处理器运行的算法。
  • @sandundhammika:规范中非常清楚地记录了它——第 6.10.3 节——尽管有许多未定义的行为角。

标签: c++ c c-preprocessor


【解决方案1】:

阅读您的问题的答案here

问题是当你有一个 宏替换,预处理器 只会扩展宏 递归如果既不是字符串化 运算符 # 也不是令牌粘贴 运算符## 应用于它。那么你 必须使用一些额外的层 间接,你可以使用 标记粘贴运算符 递归扩展参数

【讨论】:

  • 这就是为什么会有BOOST_PP_CAT :)
  • 上面的引用不正确,或者至少不完整。要扩展宏,您需要两个间接级别(在 VS2017 中测试,并在 Gnu cpp 中报告相同)。我想听听为什么需要第二级间接的解释。只有一级间接,没有任何“#”或“##”,不会扩展宏。但是第 2 级可以。
【解决方案2】:

执行连接[ref]时,标记连接不会扩展宏。

要解决这个问题,您可以使用间接级别,并让预处理器在连接之前扩展宏。

#define STEP1(x, y)    STEP2(x, y)    // x and y will be expanded before the call to STEP2
#define STEP2(x, y)    x ## y         // x and y will not be expanded, just pasted

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 2018-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多