Detect presence or absence of arguments in a C macro

本秂侑毒 提交于 2019-12-04 07:21:18

In C99 it is possible to detect if a macro argument is empty, but making that robust against all odds that may appear in that argument (arguments that are themselves expanding, contain () and stuff like that) is difficult. My macro package P99 implements such a thing, so you wouldn't have to worry too much. With that your macro can be implemented as

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

As its name indicates, P99 is only building on C99 features for that.

#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)

Note that if this were possible in C99, then it would be possible to simulate ##__VA_ARGS__, like so:

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

Then any instance of , ##__VA_ARGS__ could be replaced by PREPEND_COMMA_IF_NONEMPTY(__VA_ARGS__).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!