C &引用##&引用;在printk中,##是什么意思

C &引用##&引用;在printk中,##是什么意思,c,c-preprocessor,C,C Preprocessor,我不明白的是 #define ext4_debug(f, a...) \ do { \ printk(KERN_DEBUG "EXT4-fs DEBUG (%s, %d): %s:", \ __FILE__, __LINE__, __func__); \ printk(KERN_DEBUG f, ## a);

我不明白的是

#define ext4_debug(f, a...)                     \
    do {                                \
        printk(KERN_DEBUG "EXT4-fs DEBUG (%s, %d): %s:",    \
            __FILE__, __LINE__, __func__);          \
        printk(KERN_DEBUG f, ## a);             \
    } while (0)
有谁能帮我理解这行的意思吗?
谢谢

这是可变宏(具有多个可变参数的宏)的标记。其特定于gcc的指令,允许在
ext4\u debug()
中的
f
之后输入0个或多个参数。这意味着,
f
参数是必需的,
a
可能存在,也可能不存在


这与
printf(const char*fmt,…)
相同,其中,
fmt
是必需的,其他参数是可选的,取决于
fmt
。请参阅本文档中的最后一条语句:

如果您传入0个参数,它可以使可变宏(可以接受多个参数的宏)工作

从GCC手册中的:

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

printk(KERN_DEBUG f, ## a); 
当使用
eprintf
宏时,变量参数被省略,那么##前面的逗号将被删除。如果传递的参数为空,则不会发生这种情况;如果##前面的标记不是逗号,也不会发生这种情况

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

如果不使用此选项,则会扩展到
frpintf(stderr,“success!\n”,)
,这是一个语法错误。

@Insilico这是不正确的人,问的问题不同。它与变量宏的预处理器指令“###”有关,请注意,您只使用了
##a
,而不是
g#a
。Aniket是对的,这不是重复的,因为
#a
在该上下文中的含义与在该问题中给出的上下文中的含义不同。每个人都投票以重复的方式结束:在这样做之前,请仔细阅读。确切地说,我一直在告诉人们,这不是象征性的粘贴。请重新投票,这个问题不是重复的,并且被一些人在不知情的情况下关闭了。这个问题有着微妙的不同和不同original@Aniket我已经投了重新开放的一票;我怀疑你和我都这样做了。谢谢你纠正这里的人;当每个人都在错误的答案或错误的投票决定上跳得太快时,这是令人沮丧的。
eprintf ("success!\n")
     ==> fprintf(stderr, "success!\n");