C/C++ 可变数量参数的宏定义
在 1999 年的 ISO C 标准中,宏可以声明为接受可变数量的参数,就像函数一样。定义宏的语法类似于函数的语法。下面是一个例子:
#define debug(format, ...) fprintf (stderr, format, __VA_ARGS__)
这里的…
是一个可变参数。在调用这样的宏时,它代表零个或多个参数。这组标记替换了宏主体中出现的标识符 __VA_ARGS__
。
GCC 长期以来一直支持可变参数宏,并使用不同的语法,允许您像任何其他参数一样为变量参数命名。下面是一个例子:
#define debug(format, args...) fprintf (stderr, format, args)
这在所有方面都等同于上面的 ISO C 示例,但可以说更具可读性和描述性。
但是使用过上面两种形式的可变参数宏之后会发现一个问题,就是不能不传变量参数。
在标准 C 中,不允许完全忽略变量参数;但是你可以传递一个空参数。例如,👇🏻调用在 ISO C 中无效,因为字符串后没有逗号:
debug ("A message")
为了解决这个问题,CPP 对与标记粘贴运算符“##”一起使用的变量参数进行了特殊处理。形式如下:
#define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
如果变量参数被省略或为空,“##”运算符会导致预处理器删除它前面的逗号。如果在宏调用中提供了一些变量参数,GNU CPP 会将变量参数放在逗号之后。就像任何其他粘贴的宏参数一样,这些参数不是宏扩展的。