我看过这个片段:
#define kthread_create(threadfn, data, namefmt, arg...) \
kthread_create_on_node(threadfn, data, -1, namefmt, ##arg)
- 代表什么
##
? ##
当它出现在宏之外是什么意思?
我看过这个片段:
#define kthread_create(threadfn, data, namefmt, arg...) \
kthread_create_on_node(threadfn, data, -1, namefmt, ##arg)
##
?##
当它出现在宏之外是什么意思?与其他答案相反,这实际上是 GCC 扩展。直接粘贴变量 args 时,如果没有传递额外的 args,则会出现问题。因此,GCC##
在与__VA_ARGS__
或 varargs 变量(用 声明argname...
)一起使用时会生成。如果它包含一个值,则粘贴,如果不包含,则删除前面的逗号。
此扩展的文档在这里:
其次,“##”标记粘贴运算符放在逗号和变量参数之间时具有特殊含义。如果你写
#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)
并且在使用 eprintf 宏时省略了变量参数,那么 '##' 之前的逗号将被删除。如果您传递一个空参数,则不会发生这种情况,如果 '##' 前面的标记不是逗号,也不会发生这种情况。
eprintf ("success!\n") ==> fprintf(stderr, "success!\n");
上面的解释对于唯一的宏参数是可变参数参数的情况是模棱两可的,因为试图区分根本没有参数是空参数还是缺少参数是没有意义的。在这种情况下,C99 标准清楚地表明逗号必须保留,但是现有的 GCC 扩展用于吞下逗号。因此,CPP 在符合特定 C 标准时保留逗号,否则将其删除。
这“粘贴”了传入arg
宏扩展的任何内容。例子:
kthread_create(threadfn, data, namefmt, foo, bar, doo);
扩展为:
kthread_create_on_node(threadfn, data, -1, namefmt, foo, bar, doo);