这是Linux内核源代码的摘录。 stem##
的用法是什么?第一次见到c
#define __pcpu_size_call_return(stem, variable) \
({ typeof(variable) pscr_ret__; \
__verify_pcpu_ptr(&(variable)); \
switch(sizeof(variable)) { \
case 1: pscr_ret__ = stem##1(variable);break; \
case 2: pscr_ret__ = stem##2(variable);break; \
case 4: pscr_ret__ = stem##4(variable);break; \
case 8: pscr_ret__ = stem##8(variable);break; \
default: \
__bad_size_call_parameter();break; \
} \
pscr_ret__; \
})
最佳答案
##
运算符是预处理器操作,它将 token 粘合在一起以形成单个 token 。
假设您要基于公共(public)前缀调用两个函数,每次都传递一个参数并允许对其进行更改。
您不能使用:
#define CallBoth(pref,arg) \
{ \
arg = pref A (arg); \
arg = pref B (arg); \
}
因为替换后的
pref
和A
(或B
)将是不同的标记。同样,您不能使用:#define CallBoth(pref,arg) \
{ \
arg = prefA (arg); \
arg = prefB (arg); \
}
因为不会替换
prefA
或prefB
。为此,您可以使用:
#define CallBoth(pref,arg) \
{ \
arg = pref##A(arg); \
arg = pref##B(arg); \
}
并将替换后的
pref
和A
(或B
)串联到单个 token 中。这样,如果您输入:CallBoth(xyzzy,intVar);
它将被翻译为:
{
intVar = xyzzyA(intVar);
intVar = xyzzyB(intVar);
}
没有此功能,就无法以表示功能名称的单个标记结束。
如您所引用的文件中的注释中所述:
因此,根据提供给宏的变量的大小,它将调用以下项之一:
stem1(variable)
stem2(variable)
stem4(variable)
stem8(variable)
其中
stem
和variable
作为参数提供给宏。或者,如果这些大小均不相关,它将调用__bad_size_call_parameter()
。因此,一个电话:
char char_var;
__pcpu_size_call_return(xyzzy,char_var)
将导致通话:
xyzzy1(char_var):
int int_var;
__pcpu_size_call_return(xyzzy,int_var)
将导致通话:
xyzzy4(int_var)
其中
sizeof(int) == 4
。关于c - `##`在C中是什么意思?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17058436/