使用MSVC扩展__VA_ARGS__

时间:2015-09-04 13:22:34

标签: 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 但完全没有解释,所以我不能适应我自己的情况,因为我无法理解它。

您能解释一下这种解决方法的工作原理吗?

1 个答案:

答案 0 :(得分:10)

有问题的解决方法是:

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

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

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

G(1, 2, 3)

...到......

EXPAND( F(1, 2, 3) )

...将1, 2, 3视为单个令牌。然而,当预处理器重新扫描以进行其他替换时,该标记化不再重要:它将123视为宏F()的单独参数,并将其扩展为希望产生宏EXPAND()的参数,它只是用它自己替换它。

如果您觉得奇怪的是它按预期工作,但没有EXPAND()的版本不起作用(在MSVC中),那么你是对的。