我正在读一本关于C编程语言的书,我发现:
#define cat(x,y) x##y
#define xcat(x,y) cat(x,y)
Run Code Online (Sandbox Code Playgroud)
调用cat(cat(1,2),3)产生错误,而调用xcat(xcat(1,2),3)产生预期结果123.
两者的工作方式有何不同?
替换列表依赖的宏##通常不能以嵌套方式调用.
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)
Run Code Online (Sandbox Code Playgroud)
写作xcat(xcat(1,2),3)会奏效.随着预处理器扩展外部调用xcat,它也将扩展xcat(1,2); 区别在于xcat替换列表不再包含##.
xcat(xcat(1,2),3) ==> cat(12, 3) ==> 12##3 ==> 123
Run Code Online (Sandbox Code Playgroud)