它在 C++ std 16.3.4 中说:
重新扫描生成的预处理标记序列 [来自宏调用替换],以及源文件的所有后续预处理标记,以替换更多宏名称。
如果在替换列表的扫描过程中找到被替换的宏的名称(不包括源文件的其余预处理标记),则不会替换它。
此外,如果任何嵌套替换遇到被替换的宏的名称,它不会被替换。
这些未替换的宏名称预处理标记不再可用于进一步替换,即使它们稍后在该宏名称预处理标记将被替换的上下文中进行(重新)检查。
嵌套宏替换到底是什么?
具体考虑:
#define f(x) 1 x
#define g(x) 2 x
g(f)(g)(3)
我本来期望以下内容:
g(f)(g)(3) <-- first replacement of g, ok
2 f(g)(3) <-- nested replacement of f, ok
2 1 g(3) <-- second nested replacement of g, don't replace, stop
然而 gcc 出人意料地进行了 g 的第二次替换,产生:
2 1 2 3
有任何想法吗?
更新:
经过大量研究,让我用一个更简单的例子来澄清这个问题:
#define A(x) B
#define B(x) A(x)
A(i)(j)
这扩展如下:
A(i)(j)
B(j)
A(j)
该标准没有规定是否A(j)
应扩展为B
。委员会决定以这种方式保留它,因为不期望现实世界的程序依赖于这种行为,因此A(j)
未扩展和扩展A(j)
都B
被认为是一致的。