GCC项目在每年的三/四月份都会作出重大更新。三月即将到来,GCC项目的工程师们正忙着GCC 6的发布。我将在百忙之中抽出一点时间,简短地谈论一些GCC 6的新特性。
警告
GCC力图实现一些警告,这些警告可以帮助开发者在编译时发现错误,而不是让潜在的危险代码被默默接受并最终部署。对于 GCC 6,主要增加的是警告如下:
误导性的缩进:对误导性缩进进行警告的目的是检测出代码结构中与人类理解不相符的代码块。最明显的例子就是 2014年的“Apple SSL”bug,不恰当的缩进看上去是将GOTO语句放在了IF条件语句里面,而实际上呢并没有放在IF的判断分支内。更多的细节见David Malcolm的一篇博客。
同值比较:代码中将一个对象跟它自己比较或者跟始终与同一值比较的情况,通常是代码中的笔误。GCC 6将对这种比较进行警告。
重复的条件:GCC 6将对IF-ELSE-IF比较链中重复的条件进行警告。
负移位值和移位溢出: GCC现在将对左移一个负值或者左移溢出进行警告。这种行为通常会导致未定义的结果,相比于运行时产生未定义结果,在编译时就报出警告是更明智的选择。
空引用:GCC更积极的检测那些由于空指针引用或者返回空值引起错误和未定义行为的逻辑路径,或者将空值赋给明确要求非空的函数参数的情况。
特性
每一个版本的gcc都会带来各种新的特性,这些新特性让使用GCC开发变得更加容易。即将到来的GCC 6版本的亮点包括:
OpenMP 4.5:OpenMP API提供了一组简单、但高度灵活的接口来开发并行C、C++和Fortran程序。2015年11月发布了OpenMP 4.5规范,该规范在现有的OpenMP4.0基础上有了很多改进。GCC 6将为C和C++提供OpenMP 4.5的支持,对Fortran提供OpenMP 4支持以及对offloading一定程度的支持,尤其对于Intel MIC处理器。
段寄存器支持: x86/x86_64是一个分段的内存架构,但是GCC很大程度上忽略了Intel架构这方面的特性,而是依靠隐含的段寄存器。底层代码比如linux内 核或者glibc通常必须意识到分段体系结构,传统上采用汇编语句进行显式的段寄存器操作。从GCC 6起,变量在声明时就可以指定到特殊的段,使用这些内存中变量时显式的段寄存器就会被操作。
增强位置和其他诊断工作:GCC 6的诊断机制引入了“增强位置”特性。这个特性允许CC跟踪一定范围的诊断信息,而不仅仅是单个点。举个例子,一个复杂表达式中的有疑问的子表达式可以被 识别出来并向开发人员强调。诊断现在也包括“修复”性提示,建议开发者如何修改错误的代码。这个特性将会在David Malcolm的另一篇博客中详细介绍。
目标克隆:GCC6 增加了一个新的“目标克隆”属性,用于指明特定函数需为不同的ISA变量进行多次编译,并创建程序分发器来检测这些正在使用中的ISA并调用适合的克隆。这使得对ISA的不同版本提供”特殊运行”程序支持更为容易。
扩展存数规则:GCC6 新增一个新的pragma“scalar_storage_order”,用于指定在一个结构内字段的字节顺序。如果目标的字节顺序不同于正在被访问的对象的字节顺序,GCC6会自动生成代码来按需byte交换这些对象。
卸载/HSA:GCC5 最初已经支持通过OpenMP来卸载到MIC,通过OpenACC卸载到Nvidia GPUS. GCC6改进了这些性能并新增了通过HSA加速器来卸载。
语言和运行时
GCC 6 现在的默认值是 C++ 14. GCC 6 现在包括 C++ Concepts.
C++运行时库现在支持特殊的数学函数 (ISO/IEC 29124:2010)
支持 C++17 的实验功能
std::uncaught_exceptions
unique_key maps 的 try_emplace 和 insert_or_assign
用于访问容器和数组的非成员函数 std::size, std::empty 和 std::data
std::invoke
std::shared_mutex
std::void_t 和 std::bool_constant
实验性的支持文件系统技术规范
实验支持大多数图书馆基本技术规范,包括 shared_ptr 多态性内存资源和阵列支持第二个版本
矩阵相乘的 intrinsic 现在内联在 Fortran 前端简单的情况。
当然,你可以找到和尝试更多的优化和修正。我甚至不会试图枚举所有发生在这个空间。这与以前的发布一样,只要我们可以,我们将尽可能的提高所产生的代码和修复更多报告的错误。