2016-09-02 16 views
13

我有这样一个宏:C预处理程序删除后面的逗号

#define C(a...) (char *[]){ a, 0 } 

这适用于非空的论点:

C("a", "b") => (char *[])("a", "b", 0 } 

但我想删除尾随逗号时提供一个空参数:

C() => (char *[]){ , 0 } 

这可能吗?

+1

目前没有便携的方式来做到这一点。 (我相信有一个悬而未决的提案,可以让你构建这样的东西,不过。) –

+0

我的意思是,看看Boost.Preprocessor,也许有一些神奇的东西可以实现这一点。 (这也应该用C工作。) –

+0

没问题,我只是好奇,如果有可能的话。因为它不是,所以我只是定义了一些类似于'#define C0(char * []){0}的东西' –

回答

4

至少在GCC 5.4.0,在Cygwin(default -std=gnu11),这似乎做你想做的(假设我正确理解你的问题):

#define C(a...) (char *[]){ a 0 } 
           ^no comma!  
C("a", "b",) 
     ^comma here 
=> (char *[])("a", "b", 0 } 

C() 
=> (char *[]){ 0 } 

测试与gcc -E并没有其他的命令行选项。

编辑正如@KerrekSB所述,这是不可移植的。的GCC preprocessor docs有这样说的(强调):

以上的说明是不明确的关于其中唯一的宏参数是一个可变参数参数的情况下,因为它是〔如在这种情况下,编。]试图区分根本没有论据是否是一个空洞的论证或缺少的论证毫无意义。在这种情况下,C99标准清楚地表明逗号必须保持不变,但是现有的GCC扩展用于吞下逗号。 因此CPP在符合特定C标准时保留逗号,否则将丢弃它。

所以上述在GCC中运行良好,但可能不会在其他编译器上运行。但是,它对我的​​工作gcc -std=c90 -E(或c99c11)。

+0

在美学意义上,必须在宏的每次调用中输入尾随逗号是个小麻烦,说话是不值得的,但从技术上看,这是该问题唯一的(现在)实际解决方法。 –