检测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__)
替换。