c中的##是什么?

时间:2012-08-21 10:48:15

标签: c gcc syntax c-preprocessor

我看过这个片段:

#define kthread_create(threadfn, data, namefmt, arg...) \
    kthread_create_on_node(threadfn, data, -1, namefmt, ##arg)
  1. ##代表什么?
  2. ##出现在宏外时的含义是什么?

2 个答案:

答案 0 :(得分:10)

与其他答案相反,这实际上是GCC扩展。直接粘贴变量args时,如果没有传递额外的args则会出现问题。因此,GCC在与##或varargs变量(用__VA_ARGS__声明)时使用argname...。如果它包含值,则粘贴,如果不包含,则删除以前的逗号。

此扩展程序的文档为here

  

其次,'##'标记粘贴运算符在逗号和变量参数之间具有特殊含义。如果你写

#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)
     

并且在使用eprintf宏时省略变量参数,然后将删除“##”之前的逗号。如果传递一个空参数,则不会发生这种情况,如果“##”前面的标记不是逗号,也不会发生这种情况。

eprintf ("success!\n")
      ==> fprintf(stderr, "success!\n");
     

上述解释对于唯一的宏参数是变量参数参数的情况是模棱两可的,因为尝试区分根本没有参数是空参数还是缺少参数是没有意义的。在这种情况下,C99标准很清楚,逗号必须保留,但现有的GCC扩展名用于吞下逗号。因此,CPP在符合特定C标准时会保留逗号,否则会丢弃它。

答案 1 :(得分:1)

这会“粘贴”arg中传递给宏扩展的任何内容。 例如:

kthread_create(threadfn, data, namefmt, foo, bar, doo);

扩展为:

kthread_create_on_node(threadfn, data, -1, namefmt, foo, bar, doo);