C++ #宏调用中的ifdef可用于gcc,但不能用于msvc
我有一个宏类型列表,它接受可变参数。我想要像这样的东西C++ #宏调用中的ifdef可用于gcc,但不能用于msvc,c++,visual-c++,gcc,macros,variadic-macros,C++,Visual C++,Gcc,Macros,Variadic Macros,我有一个宏类型列表,它接受可变参数。我想要像这样的东西 typedef TYPELIST(A ,B ,C ,D #ifdef BLA_ ,E #endif ,F) 这在gcc中非常有效。但是,当我尝试用MSVC编译它时,它会将ifdef和endif解析为宏参数。我知道一种方法是将宏调用放入ifdef中。然而,如果我有一个巨大的列表,并且
typedef TYPELIST(A
,B
,C
,D
#ifdef BLA_
,E
#endif
,F)
这在gcc中非常有效。但是,当我尝试用MSVC编译它时,它会将ifdef和endif解析为宏参数。我知道一种方法是将宏调用放入ifdef中。然而,如果我有一个巨大的列表,并且如果我想根据定义的不同宏包含不同的类,那么它将变得单调乏味。这在gcc中工作而不在MSVC中工作,有什么特别的原因吗?在宏中使用#ifdef是不合法的。我有点惊讶gcc允许这样做。恐怕你必须在整个定义中加入#ifdef,即
#ifdef BLA_
typedef TYPELIST(a,b,c,d,e,f)
#else
typedef TYPELIST(a,b,c,d,f)
#endif
根据标准(§16.3.4/3),“产生的
宏替换的预处理令牌序列未按以下方式处理
一个预处理指令,即使它类似于一个“[…]”。如果
g++在这里处理#ifdef/#endif
,这是
编译器(至少如果您要求符合标准,
e、 g.带有
-std=…
)是的,在宏调用中放置预处理器指令不是合法的C++。如果您尝试这样做,编译器可以随心所欲。正如你所看到的,g++和MSVC做了不同的事情。@john,你的评论不应该是一个更好的答案吗?GCC和MSVC的哪个版本?@AdriC.S。这是对他的问题的回答,但不是对他的问题的真正回答。也许其他人可以建议一个可行的解决方案。gcc-4.7和cl-16.00.30319.01但它可以与g++和clang++一起使用。我还尝试使用-std=c++03
强制标准一致性,但它仍然没有抱怨。实际上,这不是一个错误,只是一个错误。16.3/11(谈论类似宏的函数的参数):“如果参数列表中有一系列预处理标记,否则将用作预处理指令,则行为未定义。”啊,是的。“扩展到预处理器指令”和参数列表中的预处理标记之间存在差异。因此,就标准而言,这不是一个错误;对于他们如何处理未定义的行为,这只是一个糟糕的选择(虽然不是一个选择,它可能与他们如何标记有关)。从形式不良的意义上讲,这并不违法,它只是有未定义的行为。所以gcc可以接受它。