Jav*_*Man 5 c++ macros c-preprocessor
我正在研究关于C++预处理器如何处理宏替换的C++标准(我需要自己实现C++预处理器的一个子集).这是我为学习创建的一个例子:
#define a x
#define x(x,y) x(x+a, y+1)
a(x(90, 80), a(1,2))
Run Code Online (Sandbox Code Playgroud)
通过要求VC++ 2010生成预处理器输出文件,我发现上面的内容a(x(90, 80), a(1,2))
变为:
90(90+x, 80+1)(90(90+x, 80+1)+x, 1(1+x, 2+1)+1);
Run Code Online (Sandbox Code Playgroud)
但是预处理器如何提出这个输出呢?规则太复杂,无法理解.有人可以解释预处理器为提出这样的结果所做的所有步骤吗?
旧答案,订单不准确(见编辑):
让我们从你的表达开始:
Run Code Online (Sandbox Code Playgroud)a(x(90, 80), a(1, 2))
现在,既然我们已经
#define a x
扩展到:Run Code Online (Sandbox Code Playgroud)x(x(90, 80), x(1, 2)) // ^^^^^^^^^ ^^^^^^^ // arg 'x' arg 'y'
我们可以应用定义
x(x,y)
,即#define x(x,y) x(x+a, y+1)
:Run Code Online (Sandbox Code Playgroud)x(90, 80)(x(90, 80)+a, x(1, 2)+1)
还有另一个将会扩展的通行证
x(...)
.您还可以注意到,+a
上一个表达式中的那个>已扩展为+x
:Run Code Online (Sandbox Code Playgroud)90(90+a, 80+1)(90(90+a, 80+1)+x, 1(1+a, 2+1)+1) // ^^ // expanded
最后:
+a
遗骸扩大到+x
:Run Code Online (Sandbox Code Playgroud)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)
Run Code Online (Sandbox Code Playgroud)
它不会扩展到类似的东西
x(u+a+a+a+a, b+1+1+1+1)
Run Code Online (Sandbox Code Playgroud)
这是因为在x
定义宏时,其名称对内部宏定义"不可用".
另一个小注意事项:对于gcc,输出不完全相同,因为gcc在替换的标记之间添加空格(但如果删除它们将与msvc相同).
编辑:从dyp的评论,这个顺序不是确切的.实际上,首先扩展参数然后在宏表达式中替换.句子的最后一部分很重要:这意味着不重新评估宏参数列表.可以把它想象成:使用占位符代替参数扩展宏,然后扩展参数,然后用各自的参数替换占位符.所以,简而言之,这相当于我之前解释过的,但这里是正确的顺序(详细操作):
> 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)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
314 次 |
最近记录: |