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

因为替换后的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)串联到单个 token 中。这样,如果您输入:
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

关于c - `##`在C中是什么意思?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17058436/

10-13 07:32