展开c宏__VA_ARGS__个元素
expand c macro __VA_ARGS__ elements
我想定义一个这样的宏
#define ASSERT_EXIST(error, ...) some-impl-here
那我们可以这样称呼它
ASSERT_EXIST(100, a, b, c)
应该扩展到这个
if (!a_exists) return error("a is missing", 100);
if (!b_exists) return error("b is missing", 100);
if (!c_exists) return error("c is missing", 100);
其中最麻烦的部分是我无法在宏中轻松地迭代 __VA_ARGS__
。
如果您只想将可变数量的参数抛给一个函数,__VA_ARGS__
就足够了,就像您已经做的那样。要处理趋势逗号,有时您可能还需要 ##
.
如果您想遍历参数,请使用来自 <stdarg.h>
的可变参数。
有各种肮脏的技巧,您可以让可变参数宏达到某个固定的数字。但是,正确且正确的解决方案是根本不编写可变参数宏。简单地使用
是更好的做法
#define ASSERT_EXISTS(val, x) if (!x##_exists) { return error(#x " is missing", val); }
ASSERT_EXIST(100, a);
ASSERT_EXIST(100, b);
...
或者更好的是,放弃所有这些讨厌的宏,转而使用可读的标准 C。
if(!a_exists) { return error("a is missing", 100); }
if(!b_exists) { return error("b is missing", 100); }
if(!c_exists) { return error("c is missing", 100); }
当然,代码重复是不好的做法,但是秘密宏语言是非常糟糕的做法。
我想定义一个这样的宏
#define ASSERT_EXIST(error, ...) some-impl-here
那我们可以这样称呼它
ASSERT_EXIST(100, a, b, c)
应该扩展到这个
if (!a_exists) return error("a is missing", 100);
if (!b_exists) return error("b is missing", 100);
if (!c_exists) return error("c is missing", 100);
其中最麻烦的部分是我无法在宏中轻松地迭代 __VA_ARGS__
。
如果您只想将可变数量的参数抛给一个函数,__VA_ARGS__
就足够了,就像您已经做的那样。要处理趋势逗号,有时您可能还需要 ##
.
如果您想遍历参数,请使用来自 <stdarg.h>
的可变参数。
有各种肮脏的技巧,您可以让可变参数宏达到某个固定的数字。但是,正确且正确的解决方案是根本不编写可变参数宏。简单地使用
是更好的做法#define ASSERT_EXISTS(val, x) if (!x##_exists) { return error(#x " is missing", val); }
ASSERT_EXIST(100, a);
ASSERT_EXIST(100, b);
...
或者更好的是,放弃所有这些讨厌的宏,转而使用可读的标准 C。
if(!a_exists) { return error("a is missing", 100); }
if(!b_exists) { return error("b is missing", 100); }
if(!c_exists) { return error("c is missing", 100); }
当然,代码重复是不好的做法,但是秘密宏语言是非常糟糕的做法。