【问题标题】:C preprocessor expansion orderC 预处理器扩展顺序
【发布时间】:2015-11-20 14:16:59
【问题描述】:

我正在尝试使用 C 预处理器做一些事情。我有这个宏:

#define _MAX(x, y) (((x)) > ((y))) ? (x) : (y))

#define MAX1 _MAX(1,
#define MAX2 _MAX(2,0))

#define RIGHT _MAX(1,_MAX(2,0))
#define WRONG MAX1 MAX2

在这种情况下,RIGHT 给了我正确的表达式,但 WRONG,即使它相同,也会将宏扩展为空白。

在我看来,这是因为在将 MAX1 扩展为 _MAX(1, 后,它检测到有一个要扩展的 _MAX 宏,并尝试在不扩展 MAX2 的情况下进行扩展,而 MAX2 包含语句的另一半。

如果我是对的,有什么方法可以延迟 _MAX 宏扩展直到 MAX2 扩展?

【问题讨论】:

  • 只是在黑暗中刺伤,您是否尝试过在 MAX1 之前定义 MAX2 ?
  • 注意:添加双括号并不会使表达式更安全 ;)
  • 使用 gcc 我得到error: unterminated argument list invoking macro "_MAX"
  • 我听说内联函数真的很棒。

标签: c gcc c-preprocessor


【解决方案1】:

这是正确的,因为订单WRONG 正在扩展。首先它将宏扩展为

MAX1 MAX2

然后它重新扫描它以进一步扩展它,首先它将 MAX1 扩展为 _MAX(1, 并且在重新扫描时发生错误,因为它没有找到参数列表的终止。

如果您将WRONG 定义为MAX1 MAX2 ),它会毫无怨言地扩展它(但当然不是同样的扩展)。

【讨论】:

    【解决方案2】:

    C 预处理器在每次展开后扫描宏。第 6.10.3.4 节指出:

    在替换列表中的所有参数都被替换并且### 处理已经发生之后,所有的placemarker 预处理标记都将被删除。然后,重新扫描生成的预处理标记序列以及源文件的所有后续预处理标记,以替换更多宏名称。

    强制 C 预处理器在宏 A 之前扩展宏 B 的一种方法是将 B 作为参数传递给 A:

    #define _MAX(x, y) (((x)>(y))?(x):(y))
    
    #define MAX1(Y) _MAX(1,Y)
    #define MAX2 _MAX(2,0)
    
    #define NEW_RIGHT MAX1(MAX2)
    

    现在MAX2变成MAX1的一个参数,所以它的内容在MAX1的扩展过程中被扩展了。

    Demo.

    【讨论】:

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