VS 2015 Update 2中的编译器改进

C++编译器团队对编译器尝试编译非常兴奋。 Visual Studio 2015更新2 CTP 1 . 自从更新1以来,我们已经取得了许多C++ 11和C++ 14特性的一致性。一个特别重要的里程碑是 我们的标准库在更新2支持每一个C++标准库特征,这些特征已经被投票到C++ 11、C++ 14和C++ 17中。 . 为了实现这一点,除了我们的库团队做了大量的工作外,还需要对解析器进行改进。自更新1以来,我们还修复了大约300个编译器错误,其中许多错误解决了编译器中的错误代码生成问题。我们知道,破坏性的更改对开发人员来说是非常有影响的,因此我们努力确保任何可能影响当前工作的源代码的更改都是次要的和罕见的,并尽最大努力记录任何可能会影响到您的bug修复和潜在修复的领域。例如,我们改变了解析decltypes内部表达式的方式,以更好地支持表达式SFINAE。我们有一个新的警告,警告您以前的错误代码应该可以更好地帮助您诊断内存问题与不匹配的new/delete。有关可能需要更改源代码以及如何向前移动代码的建议的解析器改进的完整列表,请访问专用的MSDN页面: Visual C++ 2015更新2中的更改 .让我们深入研究一下我们在编译器2中所做的一些改进,其中很多改变帮助编译器符合现有的C++ 11和C++ 14标准的特性。我们的一些变化是前瞻性的;也就是说,我们实现了预期的C++ 17标准。我们将在这篇博文中浏览的完整列表是 constexpr ,变量模板,初始值设定项列表的顺序,模块,以及使用UTF8–让我们深入了解一下!

null

常量表达式

我们正在继续改进我们的产品 constexpr 支持。这是一个特性,允许您表示在编译时而不是在运行时运行的计算。如果你不熟悉 constexpr ,你应该看看科迪·米勒关于 constexpr 在这里: https://blogs.msdn.microsoft.com/vcblog/2015/12/02/constexpr-in-vs2015-update-1 . 我们在更新1中做了很多工作来启用 constexpr 支持STL的特性,但我们仍然在C++ 11和C++ 14上取得进展 constexpr 支持。

变量模板

变量模板是C++ 14的特性,我们实现了它帮助我们的标准库传输C++ 17的特性。如果你用过 std::is_same<T, U>::value 你会很感激的 std::is_same_v . 它是 std::is_same 类型特征。变量模板允许您删除 ::value 从C++ 11代码中使用类型特征,例如 is_signed<T>::value . 在高级情况下,可以移除C++ 11的解决方案,因为它必须声明包装类模板的静态数据成员,该模板只存在,因此您有一些参数化。那么什么是变量模板,您如何在代码中使用它们呢?变量模板是对允许在模板声明中声明变量的标准的修复。可以定义参数化常量,例如: template<typename T> constexpr T pi = T(3.1415926535897932385); 在计算圆面积的函数中使用: template<typename T> T area_of_circle_with_radius(T r) { return pi<T> * r * r; } 以前,模板声明只允许是函数、类或别名。现在,在MSVC编译器中,它也可以是一个变量。注意:我们仍在努力在VSIDE中支持IntelliSense中的变量模板。我们破例发布了这个特性,因为我们对 变量模板 (i、 例如,上述STL工作。)

初始值设定项列表的顺序

初始值设定项列表允许您在以逗号分隔的大括号列表中简单地初始化数据。例如,写这个比较容易 std::complex<double> z{1,2} 而不是分配double,然后初始化它的成员。该标准规定初始值设定项列表必须按其出现的顺序进行计算。例如,在 a{x(), y(), z()} x() 必须在 y() 必须在 z() . 这一点非常关键的一个地方是迭代元组的元素。我们以前收到过关于这个在MSVC中不起作用的反馈,例如: https://gist.github.com/DrPizza/bf8cbdf63e7a9702e90a .在更新2中,我们现在根据标准按顺序调用初始值设定项列表。如果由于初始值设定项列表中的类之间存在非平凡的依赖关系而无法执行此操作,则会发出警告。

C++模块

我们的团队一直在努力工作C++模块,一个新的C++特性,已经被C++演进工作组批准,用于技术规范,目前正在由C++核心工作组审查。模块可以帮助您改进代码的组件化,从而提高构建吞吐量。模块还将您的代码与预处理器状态隔离开来,而预处理器状态可能很难调试。它们将使开发工具更容易使用代码,因为您不必编写C++预处理器和解析器来理解接口。我们在这里写了一篇关于C++模块的深入博客文章: https://blogs.msdn.microsoft.com/vcblog/2015/12/03/c-modules-in-vs-2015-update-1 .如果在更新1中试用C++模块,您可能会注意到很多代码不起作用。我们一直在努力实现这个新功能。尝试更新2中的C++模块,你会发现更多的代码只是工作。

使用UTF-8

我们使使用UTF-8和MSVC的其他字符集变得更容易。跨平台编译包含非ASCII字符串的代码非常困难,我们称之为源字符集。而且,由于编译器根据程序运行的环境对字符串进行不同的解释,因此很难编写在不同操作系统上编译的代码,这些操作系统对非ASCII字符串的处理在任何地方都是一样的。我们称之为执行字符集。我们添加了几个新的命令行编译器选项,允许您显式指定源和执行字符集。由于UTF-8是跨平台代码中常见的字符集,因此我们还引入了一个选项,将源和执行字符集都设置为UTF-8。Jim Springfield的一篇博文解释了我们是如何处理角色集的:https://blogs.msdn.microsoft.com/vcblog/2016/02/22/new-options-for-managing-character-sets-in-the-microsoft-cc-compiler/

空基类优化

注意:空基类优化在update2中,而不是update2 CTP中 有时您会编写一个空类作为层次结构的基础。但是空类不是真的空:C++要求类有一个非零大小来确保对象标识。如果,对于给定的类 C , sizeof(C)==0 ,在指向 C 可能导致被零除(例如,如何计算 x y 在这个表达式中: &a[x] - &a[y] ? 将指针之间的距离除以元素的大小(元素的大小不能为零)。但是,尽管任何空类的大小总是非零的,但当将空类用作基类时,它的大小实际上可以为零。有一个众所周知的优化叫做“空基类优化”,它使得空基类的大小为零。MSVC以前只做了有限的优化。我们现在广泛支持更新2。目前,您必须标记每个类,您希望在其中使用 __declspec . 例如,

struct empty1 {};struct empty2 {};struct empty3 {};struct __declspec(emptyBases) MyStruct : empty1, empty2, empty3{    int i;    int j;    int k;}

我们还创建了一个编译器选项, /d1reportEmptyBasesClassLayout 以帮助确定这种优化有用的类。这个开关就是我们所说的“d1”开关,这意味着它是一个临时的、不受支持的编译器开关,有一天会被删除而不另行通知。为什么我们不在默认情况下启用空基类优化呢?优化改变了类的布局,这意味着它将是一个二进制的突破性的改变。我们尽量减少中断的更改,我们知道二进制中断的更改对开发人员来说尤其痛苦。总有一天,我们将能够做出这种突破性的改变,你将不再需要使用 __declspec . 但是现在,删除空基类的大小可以在一些代码库中节省大量的二进制大小,因此我们希望您能够在代码中适当的地方进行优化。您可以在以下博客文章中阅读有关空基类优化的更多信息: https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/

最后

在VS2015 Update 2中,除了编译器之外,您还可以享受更多的新功能 . 我们热切希望您能尝试这些改变,并通过以下评论或通常的渠道给我们反馈:电子邮件, 建议 , 连接 (对于虫子),甚至 送一个微笑 . 注意: 在上编辑了此帖子 3月31日 ’16岁来反映这一点 更新2的完整版本中提供了空的基类优化。 另请注意这篇关于VS 2015 Update 1中部分支持Expression SFINAE的帖子: https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/

© 版权声明
THE END
喜欢就支持一下吧,技术咨询可以联系QQ407933975
点赞0 分享