Clang在c++ 03模式下支持哪些c++ 11扩展?
What C++11 extensions does Clang support in C++03 mode?
新版本的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扩展有文档记录吗?
你可以在这里使用两个"特性测试"宏:
__has_feature
和__has_extension
这些类函数的宏接受一个标识符参数,即一个特性的名称。如果Clang支持该特性并将其标准化,__has_feature
的值为1,如果不支持则为0;如果Clang在当前语言中支持该特性(作为语言扩展或标准语言特性),__has_extension
的值为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)
,并在为真时使用新特性,否则在为假时绕过它。当您升级clang或使用的语言模式发生变化时,您的代码将自动适应。
至于支持哪些语言特性,哪些不支持,文档可能会有所帮助,但我发现编写这样的测试是评估当前clang版本的最快和最准确的方法。
- 是否可以通过C++扩展强制多个python进程共享同一内存
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 扩展光电二极管探测器以支持多个传感器
- C++中的VLA,扩展名为std=C++11
- OpenGL 和 GLM 矩阵无法正确扩展,总是按比例缩小
- 基于范围的 for 循环:迭代使用一个元素扩展的向量
- C++返回 Numpy 数组的 Python 扩展模块
- 扩展可变参数模板中的变量名称
- 扩展C++生成的代码的模板参数类型名称
- 我想通过带有C++和Python的插件创建一个可扩展的应用程序
- VSCode IntelliSense无法识别SDL框架的SDL_image扩展库
- 将元组类型扩展为可变参数模板?
- 如何按文件扩展名引用文件夹中的文件
- HDF5Cpp 扩展复合数据集超板问题
- MSVC中的宏观扩展问题
- 嵌套参数包扩展失败
- C4204:使用的非标准扩展:非常量聚合初始值设定项
- [temp.variadic]中关于包扩展实例化的措辞
- 我应该包含什么来制作 boost.python 扩展?