c - 宏中的参数计数

标签 c macros variadic-macros

我试图理解 C 预处理宏中的参数计数和 this answer 中的想法.我们有以下宏(为简单起见,我更改了参数的数量):

#define HAS_ARGS(...) HAS_ARGS_(__VA_ARGS__, 1, 1, 0,)
#define HAS_ARGS_(a, b, c, N, ...) N

据我所知,这个宏的目的是检查给定的可变参数是否为空。因此,在空的可变参数上,宏调用被替换为 0,这看起来不错。但是只有一个参数,它也会变成 0,我觉得这很奇怪。

HAS_ARGS(); //0
HAS_ARGS(123); //also 0
HAS_ARGS(1, 2); //1

LIVE DEMO

我想我明白了原因。在空可变参数的情况下,a 被替换为空的预处理标记,在单个参数的情况下,可变参数 a 被替换为产生相同结果的参数。

有没有办法在可变参数为空的情况下返回 0,在参数编号从 1 到 HAS_ARGS_ 宏调用中定义的情况下返回 1,而不使用逗号-吞咽或其他不合格的技巧。我是说

SOME_MACRO_F() //0
SOME_MACRO_F(234) //1
SOME_MACRO_F(123, 132) //1
//etc

最佳答案

您不能将零参数传递给 HAS_ARGS(...)。 ISO C(和 C++,至少在接下来的两年)要求省略号对应于最后一个命名参数之后的至少一个附加参数。

如果没有命名的,那么宏至少需要传递一个参数。在 HAS_ARGS() 的情况下,额外的参数只是一个空的标记序列。零参数根本不可能。

这正是答案中的用例。目标宏需要至少一个参数。所以我们可以使用一个只接受省略号的包装器来进行“过载解析”。更好的名称可能是 HAS_MORE_THAN_1_ARGS。因为这就是谓词要告诉你的。 las,我赞成这个答案的简洁性。

关于c - 宏中的参数计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54177551/

相关文章:

macros - 如何在 `defmacro` 中正确使用语法引用和取消引用

c - 在多级宏调用中将宏参数字符串化

c - 堆对象如何使用堆栈中的数据?

c - 如何解决 ‘struct iphdr’ 没有名为 ‘daddr’ 的成员之类的错误

c - Mac 中的共享内存文件夹错误 shm : Invalid argument

C - 使用 printf 显示完整输出

c - C 中的宏条件语句

macros - 在 OpenOffice Calc 中自动化图表标题

fprintf() 的跨平台宏包装器

Boost.Fusion 中的 C++ 可变参数宏?