嵌套宏和##

来自C编程语言,由KRC撰写

#define cat(x, y) x ## y 

调用cat(var, 123)产生var123 。 但是,调用cat(cat(1,2),3)是未定义的: ##的存在可以防止外部调用的参数被扩展。 因此,它产生令牌字符串cat ( 1 , 2 )3)3 (第一个参数的最后一个令牌与第二个令牌的第一个令牌的连接)不是合法令牌。

如果引入第二级宏定义,

 #define xcat(x, y) cat(x,y) 

事情更顺利; xcat(xcat(1, 2), 3)确实生成123 ,因为xcat本身的扩展不涉及##运算符。

##的属性是什么使这两个例子有所区别?

为什么第一个例子中的内部cat(1,2)没有扩展,而第二个例子中的内部xcat(1,2)是?

谢谢!

它是宏##运算符的一个(不那么众所周知的)特性,它禁止进一步扩展其参数(它只是将它们视为普通字符串)。 gcc预处理器文档的摘录:

…与字符串化一样,实际参数不是首先进行宏扩展…

也就是说, ##参数没有扩展。

通过使用您的xcat宏实现额外的间接,您正在解决该问题(一个称为参数 xcat的进程正在跳入并实际评估结果字符串两次)