考虑以下代码:
#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__
#define G(...) F(__VA_ARGS__)
F(1, 2, 3)
G(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
X = 1 and VA_ARGS = 2, 3两个宏的预期输出,这就是我用GCC得到的,但是,MSVC将其扩展为:
X = 1 and VA_ARGS = 2, 3
X = 1, 2, 3 and VA_ARGS =
Run Code Online (Sandbox Code Playgroud)
也就是说,__VA_ARGS__将其扩展为单个参数,而不是分解为多个参数.
有什么方法吗?
所以我有一个在GCC中运行良好的宏,但在微软的C++编译器中没有.我希望有人可能知道一种解决方法,或者也许可以向我解释它为什么会这样.
我确定这个宏并不完全是"标准",但它确实会帮助我.
这是宏的一个功能示例:
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)
#define FULLY_EXPANDED(count, ...) \
MAC ## count (__VA_ARGS__)
#define SEMI_EXPANDED(count, ...) FULLY_EXPANDED(count, __VA_ARGS__)
#define EXPAND_THESE(...) SEMI_EXPANDED(VA_NARGS(__VA_ARGS__), __VA_ARGS__)
#define ACTUAL_MACRO(x) parent->GetProperty<x>();
#define MAC1(a) ACTUAL_MACRO(a)
#define MAC2(a,b) MAC1(a) ACTUAL_MACRO(b)
#define MAC3(a,b,c) MAC2(a,b) ACTUAL_MACRO(c)
#define MAC4(a,b,c,d) MAC3(a,b,c) ACTUAL_MACRO(d)
#define MAC5(a,b,c,d,e) MAC4(a,b,c,d) ACTUAL_MACRO(e)
Run Code Online (Sandbox Code Playgroud)
以下是我如何使用此宏:
struct MyStructure
{
void Foo()
{
EXPAND_THESE(Property1, Property2, Property3, Property4)
}
Base * parent;
}
Run Code Online (Sandbox Code Playgroud)
以下是GCC如何扩展上述内容:
struct MyStructure
{
void …Run Code Online (Sandbox Code Playgroud) 我试图让Bloomberg的BDE库在Visual Studio 2015中编译.因为它们重新实现了编译器通常提供的标准库,所以有一些头文件的名称与标准库名称完全匹配,例如stddef.h.它们可选地允许您关闭标准库的覆盖,为此,它们重新实现的文件可选地只包括原始编译器提供的版本,例如stddef.h.他们这样做包括通过宏,如下所示:
# if defined(BSLS_COMPILERFEATURES_SUPPORT_INCLUDE_NEXT)
# include_next <stddef.h>
# else
# include BSL_NATIVE_C_LIB_HEADER(stddef.h)
# endif
Run Code Online (Sandbox Code Playgroud)
在哪里BSL_NATIVE_C_LIB_HEADER扩展到这样的东西:
#if defined(BSLS_PLATFORM_CMP_SUN) // Sun Compiler
# define BSL_NATIVE_C_LIB_HEADER(filename) <../include/filename>
#elif defined(BSLS_PLATFORM_CMP_CLANG) || defined(BSLS_PLATFORM_CMP_GNU)
// Clang and GCC use 'include_next'
#elif defined(BSLS_PLATFORM_CMP_HP) // HP Compiler
# define BSL_NATIVE_C_LIB_HEADER(filename) <../include_std/filename>
#else
// Most other compilers
# define BSL_NATIVE_C_LIB_HEADER(filename) <../include/filename>
#endif
Run Code Online (Sandbox Code Playgroud)
问题是Visual Studio 2015 引入了一些重构,将一些 C标准库头文件移动到这样的路径:C:\Program Files (x86)\Windows Kits\10\Include\10.0.10150.0\ucrt.这显然意味着 <../include/filename>将不再找到移动的文件.问题是所有文件都没有移动.例如,iso646.h …