__VA_ARGS__ 使用 MSVC 扩展
__VA_ARGS__ expansion using MSVC
我发现了一个显示如何根据参数数量重载宏的问题:
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
被视为单个标记。但是,当预处理器重新扫描其他替换时,该标记化不再重要:它将 1
、2
、3
视为宏 F()
的单独参数,并将其扩展为希望生成宏 EXPAND()
的参数,它只是将其替换为自身。
如果您认为这按预期工作很奇怪,但没有 EXPAND()
的版本不起作用(在 MSVC 中),那么您是对的。
我发现了一个显示如何根据参数数量重载宏的问题: 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
被视为单个标记。但是,当预处理器重新扫描其他替换时,该标记化不再重要:它将 1
、2
、3
视为宏 F()
的单独参数,并将其扩展为希望生成宏 EXPAND()
的参数,它只是将其替换为自身。
如果您认为这按预期工作很奇怪,但没有 EXPAND()
的版本不起作用(在 MSVC 中),那么您是对的。