Visual C ++预处理器:可变宏调用中的__VA_ARGS__被视为单个标记

时间:2016-07-01 16:19:30

标签: c++ c visual-studio-2010 visual-c++ c-preprocessor

在GCC中,我已成功使用以下IS_1宏一段时间了。它在定义传输的令牌时扩展到传输宏的值,在未定义(或明确定义为0)时扩展为0:

// Concatenate two tokens without performing macro expansion.
#define CONCAT(A, B) A##B

// Possibly expand macros in transmitted tokens and concatenate the results.
#define EXPAND_THEN_CONCAT(A, B) CONCAT(A,B)

#define _0_1 0,1
#define IS_X_1_SUB(X,Y,...) Y

// Problem with MSC occurs here: __VA_ARGS__ all end up in sub-macro's first parameter
#define IS_X_1(...) IS_X_1_SUB(__VA_ARGS__, 0)

// This is the useful macro: expands to X's value when defined, 0 otherwise.
#define IS_1(X) IS_X_1(EXPAND_THEN_CONCAT(_0_,X))

示例用例:

#define THIS_IS_TRUE 1
IS_1( THIS_IS_TRUE )
// Expected expansion: 1

IS_1( THIS_IS_FALSE )
// Expected expansion: 0

#define ZERO 0
IS_1( ZERO )
// Expected expansion: 0

现在,我在尝试将此宏与Visual C ++的编译器一起使用时遇到了问题,其中__VA_ARGS__宏扩展中的IS_X_1显然作为单个参数传输到IS_X_1_SUB宏,它总是扩展为0。

这在以下愚蠢的例子中可见:

#define FOO(X, ...) X foo __VA_ARGS___
#define BAR(...) FOO(__VA_ARGS__, bar)
BAR(42, 42)
// expected (and actual result with GCC): 42 foo 42 bar
// output of MSC preprocessor: 42, 42 foo bar
  • 这是一个错误吗?
  • 它不应该像GCC一样工作吗?
  • 是否有解决方法或其他更便携的解决方案?

0 个答案:

没有答案