C预处理器删除尾随逗号

时间:2016-09-02 12:02:57

标签: c gcc c-preprocessor

我有一个像这样的宏:

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

这适用于非空参数:

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

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

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

这可能吗?

2 个答案:

答案 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有这个说法(强调添加):

  

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

所以上面的代码在GCC中运行良好,但在其他编译器上可能没有。但是,gcc -std=c90 -E(或c99c11)对我有用。

答案 1 :(得分:1)

检出可以在variadic macro中使用的GCC的__VA_OPT__()函数宏。

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

C("a", "b");   expands to (char *[]) { "a", "b" , 0 };
C();           expands to (char *[]) { 0 };

仅当__VA_OPT__()为非空时,才会扩展传递给__VA_ARGS__的参数。