2

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

2 回答 2

9

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

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

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

于 2013-06-12T05:48:07.867 回答
6

运算符是一种预##处理器操作,它将标记粘合在一起以形成单个标记。

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

您不能使用:

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

因为替换的prefand A(or B) 将是不同的标记。同样,您不能使用:

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

因为没有替代prefAorprefB将发生。

为此,您使用:

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

并且被替换的prefand A(or 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

于 2013-06-12T05:48:44.867 回答