较新版本的Clang在C++03模式下编译时支持某些C++11扩展,但在打开-Wc++11-extensions时可能会发出警告。例如,编译以下代码:
std::map<int, int> foo;
for(auto &i : foo) {
}clang test.cpp -std=c++03结果显示以下警告:
test.cpp:5:6: warning: 'auto' type specifier is a C++11 extension
[-Wc++11-extensions]
for(auto &i : foo) {
^
test.cpp:5:14: warning: range-based for loop is a C++11 extension
[-Wc++11-extensions]
for(auto &i : foo) {但是编译成功了,生成了正确的代码。但是,尝试使用统一初始化(std::map<int, int> foo{{1,2},{3,4}};)会因语法错误而失败。
在我的例子中,我有一个现有的不可变库,由于一些兼容性问题,它只在C++03模式下编译;开发人员表示他们将在“不久的将来”支持C++11。我现在想使用C++11特性来编写针对这个库的代码,这样当他们使他们的库与C++11兼容时,我就不必再回去“现代化”代码了。Clang的C++11扩展似乎非常适合这个目的,但我不确定我能用到什么。Clang的C++11扩展是否有文档记录?
发布于 2013-03-25 02:53:33
你可以在这里使用两个“功能测试”宏:
__has_feature和__has_extension
这些类似函数的宏接受单个标识符参数,即功能的名称。如果Clang支持该功能并在当前语言标准中进行了标准化,则__has_feature的计算结果为1;如果不支持,则__has_extension的计算结果为0;如果Clang在当前语言中支持该功能(作为语言扩展或标准语言功能),则该功能的计算结果为1;如果不支持,则为0。
下面记录了这些宏和标识符:
http://clang.llvm.org/docs/LanguageExtensions.html
在您的特定示例中,以下HelloWorld信息最丰富:
#if __has_extension(cxx_generalized_initializers)
#warning __has_extension(cxx_generalized_initializers) is true
#else
#warning __has_extension(cxx_generalized_initializers) is false
#endif
#if __has_feature(cxx_generalized_initializers)
#warning __has_feature(cxx_generalized_initializers) is true
#else
#warning __has_feature(cxx_generalized_initializers) is false
#endif
#if __has_extension(cxx_range_for)
#warning __has_extension(cxx_range_for) is true
#else
#warning __has_extension(cxx_range_for) is false
#endif
#if __has_feature(cxx_range_for)
#warning __has_feature(cxx_range_for) is true
#else
#warning __has_feature(cxx_range_for) is false
#endif
int main()
{
}对我来说,对于-std=c++03,它输出:
test.cpp:4:2: warning: __has_extension(cxx_generalized_initializers) is false [-W#warnings]
#warning __has_extension(cxx_generalized_initializers) is false
^
test.cpp:10:2: warning: __has_feature(cxx_generalized_initializers) is false [-W#warnings]
#warning __has_feature(cxx_generalized_initializers) is false
^
test.cpp:14:2: warning: __has_extension(cxx_range_for) is true [-W#warnings]
#warning __has_extension(cxx_range_for) is true
^
test.cpp:22:2: warning: __has_feature(cxx_range_for) is false [-W#warnings]
#warning __has_feature(cxx_range_for) is false
^
4 warnings generated.而使用-std=c++11时,输出更改为:
test.cpp:2:2: warning: __has_extension(cxx_generalized_initializers) is true [-W#warnings]
#warning __has_extension(cxx_generalized_initializers) is true
^
test.cpp:8:2: warning: __has_feature(cxx_generalized_initializers) is true [-W#warnings]
#warning __has_feature(cxx_generalized_initializers) is true
^
test.cpp:14:2: warning: __has_extension(cxx_range_for) is true [-W#warnings]
#warning __has_extension(cxx_range_for) is true
^
test.cpp:20:2: warning: __has_feature(cxx_range_for) is true [-W#warnings]
#warning __has_feature(cxx_range_for) is true
^
4 warnings generated.对于您的用例,您可以在代码中使用__has_extension(cxx_generalized_initializers),并在true时使用新功能,否则在false时解决它。然后,当您升级clang或更改所使用的语言模式时,您的代码将自动进行调整。
至于支持哪些语言功能,哪些不支持,文档可能会有所帮助,但我发现编写上面这样的测试是评估我当前的clang版本的最快、最准确的方法。
https://stackoverflow.com/questions/15601745
复制相似问题