【问题标题】:expand c macro __VA_ARGS__ elements展开 c 宏 __VA_ARGS__ 元素
【发布时间】:2019-06-12 02:17:18
【问题描述】:

我想定义一个这样的宏

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

【问题讨论】:

  • 您需要限制可以传递给ASSERT_EXIST 宏的变量数量。 AFAIK,没有办法编写一个可以扩展所有传递给它的参数的宏。
  • 查看Boost Preprocessor 库(名义上适用于C++,但也完全适用于C)。它具有处理这些要求的工具,至少对于合理大小的参数列表而言。如果您坚持使用 300 个参数,您可能需要做一些额外的工作。另请参阅Macro returning the numnber of arguments it is given in C 和相关问题。

标签: c macros variadic-functions


【解决方案1】:

有各种肮脏的技巧可以让可变参数宏工作到某个固定数字。但是,正确和正确的解决方案是根本不编写可变参数宏。简单地使用是更好的做法

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

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

【讨论】:

  • 我同意你的观点,实际上这并不意味着很多。
【解决方案2】:

如果您只想向函数抛出可变数量的参数,__VA_ARGS__ 已经足够了。要处理趋势逗号,有时您可能还需要##

如果您想遍历参数,请使用来自<stdarg.h> 的可变参数。

stdarg.h

【讨论】:

  • 可变参数与可变参数宏无关
猜你喜欢
  • 2012-08-01
  • 1970-01-01
  • 2021-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-01
  • 2014-02-14
  • 2018-10-14
相关资源
最近更新 更多