简体   繁体   English

嵌套宏和##

[英]Nested macros and ##

From The C Programming Language, by KRC 来自C编程语言,由KRC撰写

After

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

the call cat(var, 123) yields var123 . call cat(var, 123)产生var123 However, the call cat(cat(1,2),3) is undefined: the presence of ## prevents the arguments of the outer call from being expanded. 但是,调用cat(cat(1,2),3)是未定义的: ##的存在可以防止外部调用的参数被扩展。 Thus it produces the token string cat ( 1 , 2 )3 and )3 (the catenation of the last token of the first argument with the first token of the second) is not a legal token. 因此,它产生令牌字符串cat ( 1 , 2 )3)3 (第一个参数的最后一个令牌与第二个令牌的第一个令牌的连接)不是合法令牌。

If a second level of macro definition is introduced, 如果引入第二级宏定义,

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

things work more smoothly; 事情更顺利; xcat(xcat(1, 2), 3) does produce 123 , because the expansion of xcat itself does not involve the ## operator. xcat(xcat(1, 2), 3)确实产生123 ,因为xcat本身的扩展不涉及##运算符。

What is the property of ## that makes the difference between the two examples? ##的属性是什么使这两个例子之间产生差异?

Why is the inner cat(1,2) in the first example not expanded, while the inner xcat(1,2) in the second example is? 为什么第一个例子中的内部cat(1,2)没有扩展,而第二个例子中的内部xcat(1,2)是?

Thanks! 谢谢!

It is one of the (not-so-well-known) characteristics of the macro ## operator that it inhibits further expansion of its arguments (it just considers them plain strings). 它是宏##运算符的一个(不那么众所周知的)特性,它禁止进一步扩展其参数(它只是将它们视为普通字符串)。 An excerpt from the gcc pre-processor docs: gcc预处理器文档的摘录:

...As with stringification, the actual argument is not macro-expanded first... ...与字符串化一样,实际参数不是首先进行宏扩展...

That is, arguments to ## are not expanded. 也就是说, ##参数没有扩展。

By implementing the additional indirection using your xcat macro you are working around the problem (A process that is called the argument prescan is jumping in and actually evaluates the resulting string twice) 通过使用您的xcat宏实现额外的间接,您正在解决该问题(一个称为参数 xcat的进程正在跳入并实际评估结果字符串两次)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM