RFC 68:C++ 11编译模式

作者:

库尔特·施韦尔

联系方式:

schwehr@google.com/schwehr@gmail.com

起动:

2017年4月11日

通过:

2017年9月11日

状态:

采用,在GDAL2.3中实现

此RFC基于 GEOS RFC 5 作者:MateuszŁoskot。

总结

文件建议改为 C++11 编译模式默认为整个GDAL的C++源代码。

该文件的目标是请求和达成协议,使用C++ 11作为C++编程语言标准的最低要求版本。

动机

C++ 11是1998以来C++标准的第一个主要更新。 (C++03 _是一个bug修复版本。)

支持较少的C++版本将减少开发人员和测试系统的负担。

C++ 11的功能旨在促进编写简洁、紧凑、类型安全、快捷的代码。它还提供了与C语言(C99)更好的特性兼容性。

维基百科上的文章 http://en.wikipedia.org/wiki/C++11 很好地描述了C++ 11中的所有变化。

这个 std::auto_ptr 智能指针,连同一堆其他的特性,被弃用,将从C++ 17中移除。功能如下 std::unique_ptr 提供更强的替代品。

启用C++ 11编译模式将改善编程环境,使其比C++ 98更友好。

一个社会因素:(许多)C++程序员不再享受C++ 98,允许C++ 11模式可能增加新贡献的潜力。

编译器环境

GDAL支持的编译器及其编译源代码所需的最低版本摘要

http://en.cppreference.com/w/cpp/compiler_support C++ 11的特点。

C++ 11

GCC

4.8.1+

C++11 status

Debian 8(稳定),Ubuntu15.04+,Ubuntu14.04 ppa:ubuntu-toolchain-r/test ,Fedora 19+RHEL7

叮当声

3.3+

C++11 status

Debian 8(稳定),Ubuntu 14.04+,Fedora 19+,CentOS 6(?)

MSVC

14.0+(2015年)

C++11 status

n/a

C++ 14

仅列出C++ 14编译器以进行比较:

GCC

4.9+

叮当声

3.4+

MSVC

14.0+(2015年)

计划

本建议只要求在当前的C++ 11编译模式下进行协议转换 trunk 仅分支。

该建议没有提出任何关于GDAL C++代码库的大重构的详细路线图。

GDAL代码库大于1.3M LOC,并且考虑到可用的人力与LOCs的比率,这种一步重构是不可行的。

相反,这项任务将通过baby-step方法来处理,该方法将根据沿途设置的优先级逐步转换代码库。任何破坏性重构、C++类接口的更改、C++中的更改都必须在邮件列表或bug跟踪器上公布和讨论。

IMPORTANT C++ 11重构不能更改C API或中断C API兼容性,除非基于先前RFC提出的协议。

但是,如果建议被接受,任何新的C++代码都必须是C++ 11。

必须先接受此建议,才能开始使用C++ 11特性进行任何源代码重构。

一旦被接受,第一步将是更新构建配置以要求C++ 11兼容编译器。

问题

本节概述了升级到C++ 11语言可能引起的问题。

  • 默认情况下,C++ 11析构函数现在有新的异常规范 nothrow(true) . 应该检查GDAL类的析构函数,任何允许/预期抛出异常的都必须用 nothrow(false) . 否则,只要GDAL析构函数抛出异常,现有GDAL代码库的任何用户都会发现程序终止。这样的审查无论如何都是有益的。

释放

第一次发布GDAL的C++ 11编译器要求可以是2.3.0。

C++ 14

本节阐明了C++ 14在GDAL的支持情况。

  • 一旦C++ 11作为默认编译模式,GDAL开发人员和维护人员必须确保它也成功地编译在C++ 14和C++ 17模式中。

  • 是否允许参与者添加 ifdef 对于C++ 14和C++ 17来说是什么?不,现在不行。

  • 是否有升级到C++ 14或C++ 17的计划,允许使用C++最新的特性?不,没有计划。不过,这一动议得到承认,可能会在2020年左右付诸表决。

工具书类

自我分配的发展约束

这些更改应该会对现有的GDAL/OGR代码库产生适度的影响,特别是对它的大部分代码(位于驱动程序中)的影响。如果不需要使用新提供的功能,GDAL/OGR API的现有用户也应该受到这些更改的适度影响。

GDAL已经在C++ 11构建中工作得很好,因此,对于C++ 03的初始移除,应该没有外部可见的变化。

核心更改:摘要

  1. 将configure.ac更改为删除 with_cpp11 标志,总是使用C++ 11,如果失败,则使用 AX_CXX_COMPILE_STDCXX_11 找不到C++ 11

  2. 删除GDALmake.opt.in中的@CXX11_SUPPORT@

  3. 删除不支持Travis CI和AppVeyor的C++ 11的连续生成目标

  4. 删除如果是HaveCXX11,只留下C++ 11代码

    • find . -name \*.h -o -name \*.cpp | xargs egrep 'HAVE_CXX11'

  5. CPL静态断言-> static_assert

  6. NULL > nullptr (仅用于C++代码)

  7. CPL_OVERRIDE->覆盖并移除冗余虚拟

  8. -MAX或-MAX()-> std::numeric_limits<T>::lowest()

SWIG绑定的更改

开关不会影响 C SWIG绑定使用的API。但是,可能有一些代码可以删除。

潜在的变化 NOT 包含在本RFC中

在这个RFC中有很多C++ 11的特征没有地址。见 https://en.wikipedia.org/wiki/C%2B%2B11

  • 属性

  • auto

  • consexpr

  • cstdint

  • deletedefault 对于成员函数

  • 枚举类

  • 初始值设定项列表和 std::initializer_list

  • lambda

  • 基于范围的for循环

  • 标准::正则表达式

  • 右值引用

  • 智能指针 std::unique_ptrstd::shared_ptr

  • 新字符串文字:u8“一个UTF-8字符串”,u“一个UTF-16字符串”,u“一个UTF-32字符串”,R“xml(原始内容)xml”

  • std::threadthread_local 以及相关的

  • 元组

  • 还有更多…

向后兼容性

任何使用C++ API的代码都必须使用C++ 11或更新。

不应影响C API。

GDAL 2.2和X和更老的将继续有C++ 03的支持。

测试

现有的自动测试套件应继续通过。

版本编号

虽然上面描述的更改应该对现有的应用程序C API有很小的影响,但是一些行为改变,C++级别的改变和概念的改变被认为应该是2.3版本号。

实施

执行将由库尔特·施韦尔完成。欢迎其他人加入。

投票历史

https://lists.osgeo.org/pipermail/gdal-dev/2017-September/047139.html

  • 均匀+1

  • 朱卡尔+1

  • 丹尼尔+0

  • 豪华德B+1

  • 库尔特+1