在C99规则下预处理以下3行的正确输出是什么?
#define y(x) x
#define x(a) y(a
x(1) x(2)))
顺便说一句,linux下的cpp会产生一个错误消息,但我不明白为什么答案不是简单地
1 2
假设cpp是正确的而我错了,我将非常感谢你的解释。
当找到宏时,预处理器收集宏的参数,然后在展开第一个宏之前单独扫描每个宏参数,以查找在该参数内展开的其他宏:
6.10.3.1参数替换类函数宏调用的参数确定后,进行参数替换。替换列表中的参数,除非前面有通过#或#预处理令牌或后面跟着##预处理令牌(见下文),是在其中包含的所有宏都已被替换为相应的参数扩大。在被替换之前,每个参数的预处理标记为完全宏替换,就好像它们形成了预处理文件的其余部分;没有其他的可以使用预处理令牌。
在这个特定的例子中,它看到x(1)
并展开,得到
y(1 x(2)))
然后用参数1 x(2)
标识宏调用y(1 x(2))
,并预先为宏展开该调用。在其中,它发现x(2)
扩展到y(2
,然后触发错误,因为没有y
宏的)
。注意,此时它仍然在寻找扩展第一个y
宏的参数,所以它是孤立地查看它而不考虑输入文件的其余部分,这与6.10.3.4
现在有一些问题,这是否应该实际上是一个错误,或者如果预处理器应该将此y(2
序列视为根本不是宏调用,因为没有')'。如果是后者,那么它会将y调用扩展为1 y(2
,然后将其与其他输入()
)结合并最终扩展为1 2
展开宏后,在将结果文本中的宏与周围文本组合之前,将单独尝试展开宏。因此,扩展y(1
的尝试会产生这个错误。实际上,要指定以您想要的方式工作的宏展开,同时仍然满足许多其他所需的行为(例如缺乏无限递归),这是非常困难的。