无与伦比的支架宏怪异

4 c macros c-preprocessor

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

#define y(x) x
#define x(a) y(a
x(1) x(2)))
Run Code Online (Sandbox Code Playgroud)

linux下的BTW cpp产​​生错误信息,但我不明白为什么答案不简单

1 2
Run Code Online (Sandbox Code Playgroud)

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

Chr*_*odd 6

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

6.10.3.1参数替换

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

所以在这个具体的例子中,它看到x(1)并扩展了这一点

y(1 x(2)))
Run Code Online (Sandbox Code Playgroud)

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

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