检测C宏中是否存在参数

aug*_*rar 5 c c-preprocessor variadic-macros

如何定义一个C宏IFARGS(YES, NO, ...),以便IFARGS在没有其他参数的情况下进行NO调用,并IFARGS使用一个或多个参数进行调用YES

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

Jen*_*edt 5

在C99中,可以检测到宏参数是否为空,但是要使该参数对出现在该参数中的所有可能性(这些参数本身正在扩展,包含()或类似的东西)保持鲁棒性很困难。我的宏程序包P99实现了这样的事情,因此您不必太担心。这样,您的宏可以实现为

#define IFARGS(YES, NO, ...) P99_IF_EMPTY(__VA_ARGS__)(YES(__VA__ARGS__))(NO())
Run Code Online (Sandbox Code Playgroud)

顾名思义,P99仅以此为基础建立在C99功能上。

  • @augurar,这个是我最喜欢的搜索引擎的顶部搜索:) http://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/ (2认同)

aug*_*rar 2

#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)
Run Code Online (Sandbox Code Playgroud)

请注意,如果这在 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__)
Run Code Online (Sandbox Code Playgroud)

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