Cin*_*air 13 c gcc c-preprocessor
我有一个像这样的宏:
#define C( a... ) ( char *[] ){ a, 0 }
Run Code Online (Sandbox Code Playgroud)
这适用于非空参数:
C( "a", "b" ) => ( char *[] )( "a", "b", 0 }
Run Code Online (Sandbox Code Playgroud)
但是我想在提供空参数时删除尾随逗号:
C() => ( char *[] ){ , 0 }
Run Code Online (Sandbox Code Playgroud)
这可能吗?
至少在 GCC 5.4.0 中,在 Cygwin (默认-std=gnu11
)上,这似乎可以满足您的要求(假设我正确理解您的问题):
#define C( a... ) ( char *[] ){ a 0 }
^ no comma!
C( "a", "b", )
^ comma here
=> ( char *[] )( "a", "b", 0 }
C()
=> ( char *[] ){ 0 }
Run Code Online (Sandbox Code Playgroud)
使用gcc -E
且未使用其他命令行选项进行测试。
编辑正如@KerrekSB 指出的,这是不可移植的。GCC 预处理器文档有这样的说法(强调):
对于唯一的宏参数是可变参数参数的情况,上面的解释是不明确的[如在这种情况下-Ed.],因为尝试区分根本没有参数是空参数还是丢失参数是没有意义的。在这种情况下,C99 标准明确指出必须保留逗号,但是现有的 GCC 扩展用来吞掉逗号。因此,当符合特定的 C 标准时,CPP 会保留逗号,否则会删除它。
所以上面的代码在 GCC 中工作得很好,但在其他编译器上可能不行。然而,它确实对我有用gcc -std=c90 -E
(或c99
, 或c11
)。
查看可在可变参数宏__VA_OPT__()
中使用的 GCC 函数宏。
#define C(...) (char *[]) { __VA_ARGS__ __VA_OPT__(,) 0 }
C("a", "b"); expands to (char *[]) { "a", "b" , 0 };
C(); expands to (char *[]) { 0 };
Run Code Online (Sandbox Code Playgroud)
传递给的参数仅在非空__VA_OPT__()
时才会扩展。__VA_ARGS__