检测C宏中是否存在参数

如何定义C宏IFARGS(YES, NO, ...) ,以便调用没有附加参数的IFARGS会产生NO ,并且调用带有一个或多个参数的IFARGS会产生YES

我有一个使用GCC的答案(见下文),但如果可能的话,我更喜欢C99(或其不可能性的certificate)。

在C99中,可以检测宏参数是否为空,但是对于可能出现在该参数中的所有可能性(本身正在扩展的参数,包含()和类似的东西()使其变得强大是很困难的。 我的宏包P99实现了这样的function,所以你不必太担心。 有了这个,您的宏可以实现为

 #define IFARGS(YES, NO, ...) P99_IF_EMPTY(__VA_ARGS__)(YES(__VA__ARGS__))(NO()) 

正如其名称所示,P99仅基于C99function。

 #define GET(_0, _1) _0 // Return the first of two arguments #define GET_(_0, _1) _1 // Return the second of two arguments #define JOIN(_0, _1) _0 ## _1 // Concatenate two arguments #define EJOIN(_0, _1) JOIN(_0, _1) // Expand macros and concatenate #define FIRST(_, ...) _ // Truncate everything after first comma #define EFIRST(_) FIRST(_) // Expand argument and pass to FIRST #define REST(_0, ...) __VA_ARGS__ // Remove everything before first comma #define GET_GET(...) \ EJOIN(GET, EFIRST(REST(,,##__VA_ARGS__ _))) // Branch between GET and GET_ #define IFARGS(YES, NO, ...) GET_GET(__VA_ARGS__)(YES, NO) 

请注意,如果在C99中这是可能的,则可以模拟##__VA_ARGS__ ,如下所示:

 #define PREPEND_COMMA(...) , __VA_ARGS__ #define NO_COMMA() #define PREPEND_COMMA_IF_NONEMPTY(...) IFARGS(PREPEND_COMMA, NO_COMMA, __VA_ARGS__)(__VA_ARGS__) 

然后, ##__VA_ARGS__任何实例都可以被PREPEND_COMMA_IF_NONEMPTY(__VA_ARGS__)替换。