旧答案,顺序不准确(见编辑):
让我们从你的表达开始:
a(x(90, 80), a(1, 2))
现在,由于我们有 #define a x,它被扩展为:
x(x(90, 80), x(1, 2))
// ^^^^^^^^^ ^^^^^^^
// arg 'x' arg 'y'
我们可以套用x(x,y)的定义,即#define x(x,y) x(x+a, y+1):
x(90, 80)(x(90, 80)+a, x(1, 2)+1)
还有另一个将扩展x(...) 的通道。您还可以注意到,前面表达式中 > 的 +a 已扩展为 +x:
90(90+a, 80+1)(90(90+a, 80+1)+x, 1(1+a, 2+1)+1)
// ^^
// expanded
最后:剩下的+a 扩展为+x:
90(90+x, 80+1)(90(90+x, 80+1)+x, 1(1+x, 2+1)+1)
// ^^ ^^ ^^
// expanded expanded expanded
希望没有错误。
请注意,您对x(x,y) 的定义非常模糊(对于人类而言):宏名称和参数共享相同的名称。请注意,即使没有它,宏也不是递归的,所以如果你有
#define x(u,v) x(u+a, b+1)
它不会扩展到类似
x(u+a+a+a+a, b+1+1+1+1)
这是因为在定义宏 x 时,它的名称对内部宏定义不“可用”。
另一个小提示:对于 gcc,输出并不完全相同,因为 gcc 在被替换的标记之间添加了空格(但如果删除它们,它将与 msvc 相同)。
EDIT:从 dyp 的 cmets 来看,这个顺序并不准确。实际上,参数是先展开,再代入宏表达式。这句话的最后一部分很重要:这意味着宏参数列表没有被重新评估。可以把它想象成:用占位符代替参数扩展宏,然后扩展参数,然后用它们各自的参数替换占位符。所以,简而言之,这和我之前解释的一样,但是这里是正确的顺序(详细操作):
> Expansion of a(x(90, 80), a(1, 2))
> Substitution of 'a' into 'x' (now: 'x(x(90, 80), a(1, 2))')
> Expansion of x(x(90, 80), a(1, 2)) [re-scan]
> Macro 'x(X, Y)' is expanded to 'X(X+a,Y+1)'
> Expansion of 'x(90,80)' (first argument)
> Macro 'x(X,Y)' is expanded to 'X(X+a,Y+1)'
> Argument '90' does not need expansion (ie, expanded to same)
> Argument '80' does not need expansion (ie, expanded to same)
> Substitution with 'X=90' and 'Y=80': '90(90+a, 80+1)'
> Re-scan of result (ignoring macro name 'x')
> Substitution of 'a' into 'x': '90(90+x, 80+1)'
> Expansion of 'a(1,2)' (second argument)
> Substitution of 'a' into 'x'
> Expansion of 'x(1,2)' [re-scan]
> Macro 'x(X,Y)' is expanded to 'X(X+a,Y+1)'
> Argument '1' does not need expansion (ie, expanded to same)
> Argument '2' does not need expansion (ie, expanded to same)
> Substitution with 'X=1' and 'Y=2': '1(1+a, 2+1)'
> Re-scan of result (ignoring macro name 'x')
> Substitution of 'a' into 'x': '1(1+x, 2+1)'
> Substitution with X='90(90+x, 80+1)' and Y='1(1+x, 2+1)'
Result: '90(90+x, 80+1)(90(90+x, 80+1)+a, 1(1+x, 2+1)+1)'
> Re-scan of result
> Substitution of 'a' into 'x'
Result: '90(90+x, 80+1)(90(90+x, 80+1)+x, 1(1+x, 2+1)+1)'
Last result is result of whole expansion:
90(90+x, 80+1)(90(90+x, 80+1)+x, 1(1+x, 2+1)+1)