关于C中的##预处理器 [英] About ## preprocessor in C
问题描述
给出
#define cat(x,y) x##y
呼叫 cat(a,1)
返回 a1
,但 cat(cat(1,2),3)
未定义。
但是,如果我还定义 #define xcat(x,y)cat(x,y)
,则 xcat(xcat (1,2),3)
现在为 123
。有人可以详细解释为什么会这样吗?
The call cat(a,1)
returns a1
, but cat(cat(1,2),3)
is undefined.
However if I also define #define xcat(x,y) cat(x,y)
, then the result of xcat(xcat(1,2),3)
is now 123
. Can anybody please explain in detail why this is so?
推荐答案
我同时使用GCC和Clang进行了测试。
I tested this using both GCC and Clang.
GCC给出了错误:
test.c:6:1: error: pasting ")" and "3" does not give a valid preprocessing token
Clang给出了错误:
Clang gives the error:
test.c:6:11: error: pasting formed ')3', an invalid preprocessing token
int b = cat(cat(1,2),3);
似乎正在发生的事情是编译器包装了 cat( 1,2)
放在括号内;因此,当您在代码中调用 cat(1,2)
时,它确实为您提供了(12)
。然后,再次调用 cat((12),3)
会导致((12)3)
,这不是有效的令牌,这会导致编译错误。
What appears to be happening is that the compiler wraps the result of cat(1,2)
in parentheses as soon as it is expanded; so when you call cat(1,2)
in your code, it really gives you (12)
. Then, calling cat((12),3)
again leads to ((12)3)
, which is not a valid token, and this results in a compile error.
通常的观点是使用令牌粘贴运算符(##)时,应使用两个间接级别(即,使用 xcat
解决方法)。请参阅为什么我需要对宏进行双层间接访问? 和需要将两个令牌粘贴在一起的宏应该怎么做?。
The common opinion is "when using the token-pasting operator (##), you should use two levels of indirection" (i.e., use your xcat
workaround). See Why do I need double layer of indirection for macros? and What should be done with macros that need to paste two tokens together?.
这篇关于关于C中的##预处理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!