在C中`##`是什么意思?

这是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__; \ }) 

##运算符是一个预处理器操作,它将一些令牌粘在一起形成一个令牌。

所以说你想调用两个函数基于一个通用的前缀,每次传递一个参数,并允许它被改变。

你不能使用:

 #define CallBoth(pref,arg) \ { \ arg = pref A (arg); \ arg = pref B (arg); \ } 

因为被取代的prefA (或B )将是不同的记号。 同样,你不能使用:

 #define CallBoth(pref,arg) \ { \ arg = prefA (arg); \ arg = prefB (arg); \ } 

因为prefAprefB不会被替换。

要做到这一点,你使用:

 #define CallBoth(pref,arg) \ { \ arg = pref##A(arg); \ arg = pref##B(arg); \ } 

并且被替换的prefA (或B )被连接成单个标记。 这样,如果你输入:

 CallBoth(xyzzy,intVar); 

它将被翻译成:

 { intVar = xyzzyA(intVar); intVar = xyzzyB(intVar); } 

没有这个功能,就没有办法用一个表示函数名的单个标记来结束。


正如您所引用的文件中的评论所述:

/ *分支函数将一个函数分成一组函数,这些函数被调用的对象的不同标量大小被处理。 * /

所以,根据给宏的变量的大小,它会调用下面的一个:

 stem1(variable) stem2(variable) stem4(variable) stem8(variable) 

其中stemvariable作为参数提供给宏。 或者,如果这些大小都不相关,则会调用__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

预处理运算符##提供了在宏扩展期间连接实际参数的方法。 如果替换文本中的参数与##相邻,则将参数替换为实际参数,将删除##和周围的空白区域,并重新扫描结果。 例如,宏粘贴连接它的两个参数:

 #define paste(front, back) front ## back 

所以paste(name, 1)创建令牌name1