在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