无与伦比的支架宏怪异

时间:2011-11-01 20:26:13

标签: c macros c-preprocessor

根据C99规则预处理以下3行的正确输出是什么?

#define y(x) x
#define x(a) y(a
x(1) x(2)))
Linux下的BTW cpp产​​生错误信息,但我不明白为什么答案不是简单的

1 2

假设cpp是正确的,我错了,我会非常感谢解释。

2 个答案:

答案 0 :(得分:6)

当找到宏时,预处理器收集宏的参数,然后隔离扫描每个宏参数,以便在扩展第一个宏之前在参数内展开其他宏:

  

6.10.3.1参数替换

     

在确定了调用类函数宏的参数之后,      参数替换发生。替换列表中的参数,除非在前面     通过#或##预处理令牌或后跟##预处理令牌(见下文),是    在其中包含的所有宏之后用相应的参数替换   扩大。在被替换之前,每个参数的预处理标记都是    完全宏被替换,好像它们形成了预处理文件的其余部分;没有其他     预处理令牌可用。

所以在这个具体的例子中,它会看到x(1)并扩展它,给出

y(1 x(2)))

然后使用参数y(1 x(2))标识宏调用1 x(2),并为宏扩展预扫描。其中发现x(2)会扩展为y(2,然后由于)宏没有y而触发错误。请注意,此时它仍然希望扩展第一个y宏的参数,因此它会孤立地查看它而不考虑输入文件的其余部分,这与6.10.3.4的扩展不同

现在有一些问题是,这实际上是否应该是一个错误,或者预处理器是否应该将此y(2序列视为根本不是宏调用,因为没有')'。如果它执行后者,那么它会扩展y调用1 y(2,然后将其与输入的其余部分())合并,最终扩展为1 2

答案 1 :(得分:0)

扩展宏之后,在结果文本与周围文本组合之前,尝试在生成的文本中展开宏。因此,扩展y(1的尝试会产生此错误。实际上很难指定宏扩展以你想要的方式工作,同时仍然满足许多其他所需的行为(例如缺乏无限递归)。