我正在读一本关于C编程语言的书,我发现:
#define cat(x,y) x##y
#define xcat(x,y) cat(x,y)
调用cat(cat(1,2),3)
会产生错误,而调用xcat(xcat(1,2),3)
会产生预期结果123
。
两者的工作方式有何不同?
答案 0 :(得分:5)
替换列表取决于##
的宏通常无法以嵌套方式调用。
cat(cat(1,2),3)
未按正常方式展开,cat(1,2)
产生12
,然后cat(12, 3)
产生123
。
替换列表中##
之前或之后的宏参数在替换时不会被扩展。
6.10.3.1参数替换
1在确定了调用类函数宏的参数之后, 参数替换发生。替换列表中的参数,除非在前面 通过
#
或##
预处理令牌或后跟##
预处理令牌(见下文),在其中包含的所有宏之后被相应的参数替换 扩大。在被替换之前,每个参数的预处理标记都是 完全宏被替换,好像它们形成了预处理文件的其余部分;没有其他 预处理令牌可用。
因此,cat(cat(1,2),3)
会扩展为cat(1,2)3
,因为没有名为cat(1,2)3
的宏,所以#define xcat(x,y) cat(x,y)
无法进一步扩展。
以防
xcat(xcat(1,2),3)
写作xcat
将起作用。当预处理器扩展xcat(1,2)
的外部调用时,它也会扩展xcat
;区别在于 ##
的替换列表不再包含xcat(xcat(1,2),3) ==> cat(12, 3) ==> 12##3 ==> 123
。
{{1}}