C语言 不匹配的括号宏怪异



在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的尝试会产生这个错误。实际上,要指定以您想要的方式工作的宏展开,同时仍然满足许多其他所需的行为(例如缺乏无限递归),这是非常困难的。

最新更新