展开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> 的可变参数。

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); }

当然,代码重复是不好的做法,但是秘密宏语言是非常糟糕的做法。