c - __VA_ARGS__ 扩展使用 MSVC

标签 c visual-c++ macros variadic-macros

我发现了一个问题,展示了如何根据参数的数量重载宏: Overloading Macro on Number of Arguments

但正如他们所说,它无法使用 MSVC,因为 MSVC 将 __VA_ARGS__ 扩展为单个标记而不是参数列表(arg1、arg2、arg3)。

他们指出了另一个问题,其中给出了解决方法:MSVC doesn't expand __VA_ARGS__ correctly 但根本没有解释,所以我无法理解它,因此无法适应我自己的情况。

您能否解释一下此解决方法的工作原理?

最佳答案

有问题的解决方法是这样的:

#define EXPAND( x ) x
#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__
#define G(...) EXPAND( F(__VA_ARGS__) )

这个想法是给定一个现有的可变参数宏 F():

#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__

而不是编写你想要的可变包装宏,在这种情况下,......

#define G(...) F(__VA_ARGS__)

...您使用附加的 EXPAND() 宏编写 G()F() 的实际定义不是重点,特别是对于这个例子来说,宏展开不产生有效的 C 代码并不重要。其目的是演示预处理器关于宏参数的行为。具体来说,它表明尽管 MSVC 将 __VA_ARGS__ 扩展为可变参数宏中的单个标记,但可以通过强制双重扩展来解决这个问题。

例如,使用变通方法定义,预处理器首先展开...

G(1, 2, 3)

...到...

EXPAND( F(1, 2, 3) )

... 其中 1, 2, 3 被视为单个标记。然而,当预处理器重新扫描额外的替换时,标记化不再重要:它将 123 视为宏 的单独参数code>F(),并根据需要扩展它以生成宏 EXPAND() 的参数,它只是用自身替换它。

如果您认为这按预期工作很奇怪,但没有 EXPAND() 的版本不起作用(在 MSVC 中),那么您是对的。

关于c - __VA_ARGS__ 扩展使用 MSVC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32399191/

相关文章:

c - 如何在 Linux 中编译静态库?

c - 宏和后增量

c - 类似函数的宏的错误扩展

c - sdl 不断按键

c - C 中的 getopt() 在 if 语句后无法正常工作

c - 非阻塞请求-应答方案(ZeroMQ)

c++ - Visual C++ 中的 'Bad Ptr' 是什么意思?

visual-c++ - 从整数值中提取 rgb 颜色分量

visual-c++ - 使用make_pair时在Visual Studio 2012中使用c2664

c - FLT_MAX 宏在哪里定义?