如何修复 MSVC++ (Microsoft Visual studio) 中 "macro overloading" 的可变参数宏相关问题?
How to fix variadic macro related issues with "macro overloading" in MSVC++ (Microsoft Visual studio)?
受到this kind of solution的启发,我写了下面的代码,模拟了"overloading of macros".
#include<iostream>
#define CONCATE_(X,Y) X##Y
#define CONCATE(X,Y) CONCATE_(X,Y)
#define UNIQUE(NAME) CONCATE(NAME, __LINE__)
#define NUM_ARGS_(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, TOTAL, ...) TOTAL
#define NUM_ARGS(...) NUM_ARGS_(__VA_ARGS__, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define VA_MACRO(MACRO, ...) CONCATE(MACRO, NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
#define COUT(...) VA_MACRO(_COUT, __VA_ARGS__)
#define _COUT1(X) std::cout << "1 argument\n"
#define _COUT2(X, Y) std::cout << "2 arguments\n"
#define _COUT3(X, Y, Z) std::cout << "3 arguments\n"
int main ()
{
COUT("A");
COUT("A", 1);
COUT("A", 1, 'a');
return 0;
}
这在 g++/clang++ 编译器中工作正常,输出如下:
1 argument
2 arguments
3 arguments
但是,由于与 __VA_ARGS__
:
相关的已知编译器错误,它没有给出最新 MSVC (2017) 的预期输出
1 argument
1 argument
1 argument
我根据以下 post 尝试了各种 "indirect expansions" 组合,但没有成功:
Visual studio __VA_ARGS__ issue
如何在 MSVC 中解决这个问题?
除了知道它存在之外,我对 MSVC 错误不是很有经验,但我能够在其他答案中应用解决方法 as follows:
#define MSVC_BUG(MACRO, ARGS) MACRO ARGS // name to remind that bug fix is due to MSVC :-)
#define NUM_ARGS_2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, TOTAL, ...) TOTAL
#define NUM_ARGS_1(...) MSVC_BUG(NUM_ARGS_2, (__VA_ARGS__))
#define NUM_ARGS(...) NUM_ARGS_1(__VA_ARGS__, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define VA_MACRO(MACRO, ...) MSVC_BUG(CONCATE, (MACRO, NUM_ARGS(__VA_ARGS__)))(__VA_ARGS__)
这还会在最新的 GCC 和 Clang 上生成适当的预处理器输出。得知有一种方法可以解决这个问题而无需为 "indirect expansion" 调用 MSVC_BUG
宏两次,我不会感到惊讶,但我没有找到它。
受到this kind of solution的启发,我写了下面的代码,模拟了"overloading of macros".
#include<iostream>
#define CONCATE_(X,Y) X##Y
#define CONCATE(X,Y) CONCATE_(X,Y)
#define UNIQUE(NAME) CONCATE(NAME, __LINE__)
#define NUM_ARGS_(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, TOTAL, ...) TOTAL
#define NUM_ARGS(...) NUM_ARGS_(__VA_ARGS__, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define VA_MACRO(MACRO, ...) CONCATE(MACRO, NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
#define COUT(...) VA_MACRO(_COUT, __VA_ARGS__)
#define _COUT1(X) std::cout << "1 argument\n"
#define _COUT2(X, Y) std::cout << "2 arguments\n"
#define _COUT3(X, Y, Z) std::cout << "3 arguments\n"
int main ()
{
COUT("A");
COUT("A", 1);
COUT("A", 1, 'a');
return 0;
}
这在 g++/clang++ 编译器中工作正常,输出如下:
1 argument
2 arguments
3 arguments
但是,由于与 __VA_ARGS__
:
1 argument
1 argument
1 argument
我根据以下 post 尝试了各种 "indirect expansions" 组合,但没有成功:
Visual studio __VA_ARGS__ issue
如何在 MSVC 中解决这个问题?
除了知道它存在之外,我对 MSVC 错误不是很有经验,但我能够在其他答案中应用解决方法 as follows:
#define MSVC_BUG(MACRO, ARGS) MACRO ARGS // name to remind that bug fix is due to MSVC :-)
#define NUM_ARGS_2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, TOTAL, ...) TOTAL
#define NUM_ARGS_1(...) MSVC_BUG(NUM_ARGS_2, (__VA_ARGS__))
#define NUM_ARGS(...) NUM_ARGS_1(__VA_ARGS__, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define VA_MACRO(MACRO, ...) MSVC_BUG(CONCATE, (MACRO, NUM_ARGS(__VA_ARGS__)))(__VA_ARGS__)
这还会在最新的 GCC 和 Clang 上生成适当的预处理器输出。得知有一种方法可以解决这个问题而无需为 "indirect expansion" 调用 MSVC_BUG
宏两次,我不会感到惊讶,但我没有找到它。