公告:MSVC符合C++标准

实现与C++标准的一致性对于Visual C++团队来说是一条漫长的道路。如果您最近在任何会议上看到我们,您可能已经看到了MSVC一致性幻灯片(你可以拿一份幻灯片或观看2017年CppCon演讲 在这里 完成这个幻灯片上的特性——包括C++ 11、C++ 14和C++ 17的特性——这是我们团队在过去几年中的主要目标之一。

null

图片[1]-公告:MSVC符合C++标准-yiteyi-C++库

我们很高兴地宣布,在Visual Studio 2017 15.7版中,我们实现了这些功能(技术规范正在进行中,因为它们正在进入标准。)

VisualStudio版本15.7中的MSVC编译器工具集符合C++标准!

我们不会停止我们的一致性努力——总是有新的特性、缺陷报告等等。在这些特征中有一些地方我们知道错误,但是我们相信,在这一点上,C++标准中没有应该用MSVC编译器避免的特征区域(除了下面描述的预处理器)之外,以及浮点,尚未实现)。希望我们的团队在未来能有更多的交流,因为我们会减少剩下的警告。请在博客中查看以下详细信息。

达到一致性

我们的编译器历史悠久: 二月是Visual C++产品第二十五周年 . 这个 Visual C++内置的微软C产品已有35年历史。 . 在编译器的整个历史中,我们首先关心的是保持兼容性,这样代码就不会被破坏。 我们仔细记录了为符合性所做的所有更改 ,使我们的修复程序在可能的情况下与源代码兼容,并在需要更改代码时提供解决方法。三年前, 我们公布了我们的编译器重写 . 我们已经在一个我们称之为“复兴”的过程中对编译器进行了一次大修。旧的YACC解析器和“Rejuv”递归下降解析器在我们今天的编译器中并排运行。当我们能够实现它们时,我们已经将特性从旧代码单独移动到“Rejuv”代码。这项技术使我们能够不断取得进展,同时尽量减少破坏性的变化。重写特性有时会导致一些倒退,对于给您带来的不便,我们深表歉意。然而,总体上,在现代编译器上实现现代C++特性比在我们几十年前的解析器上要容易得多,其中一些功能无法完全实现。

标准库一致性

标准库的MSVC实现最近获得了一些主要的新特性:并行算法、文件系统、constexpr字符特性、特殊数学以及对类模板参数推导的支持。我们的功能状态的详细表格如下所示。

编译器一致性

使用VisualStudio 2017版本15.7,我们将完全实现C++标准中几乎所有的功能,包括通过C++ 17实现的所有版本。其余的功能已经实现(并且将很快装运)或正在实施。这包括完成了一些我们从C++ 11/14中所做的更困难的功能:两阶段名称查找,表达式sFANEA,扩展 constexpr ,并打包扩展。每一个编译器都有bug我们在其他实现中报告了一些一致性bug,同时用新的眼光实现了旧的特性。我们将继续解决我们的缺陷,并继续实现新的特性,因为它们在标准草案中被采用。

技术规格

MSVC在许多技术规范方面也处于领先地位。MSVC拥有最完整的 模块TS的C++扩展 . 我们有最古老的 协同程序的C++扩展 最近我们重新编写了用于协同程序的优化器。微软正在推出大量同时使用模块和协同程序的产品。我们一直在研究 范围TS的C++扩展 ,以改善TS,并使MSVC达到我们可以支持的范围。而大多数 概念的C++扩展 已经被合并到C++ 20标准草案中,我们致力于在C++ 20工作中尽早实现该功能。

“但是……呢?”

我们将重点放在流行的OSS库上,同时保持大型代码库的源代码兼容性,从而推动了我们的一致性工作。一些主要的库仍然不能用MSVC正确地编译,我们正在积极地研究它们。

  • 助推。Hana:
    • 扩展 constexpr 在我们的编译器中也是一个挑战。我们有一些已知的bug,但是我们相信我们的实现是一致的。作为一个具体的例子,我们发现了大约10个阻塞 constexpr 编译时的错误 Boost Hana,“元编程标准库” . 在我们积极修复这些编译器错误的同时,如果我们将源代码变通方法更改应用到Hana,那么我们可以通过大约30-40%的Hana测试。我们目前正在完全重写constexpr求值器,以解决剩下的问题。
  • 包装扩展:
    • 包扩展很快成为C++的结构。我们的实现也在发展,因为我们移动构造来使用新的“复兴”编译器解析树。我们在可变的通用lambda、数组上的包扩展和函数模板的偏序方面有一些缺陷,这些缺陷将通过使用新的解析树来解决。我们也在修复 重写继承构造函数 正确使用包扩展。
  • 范围V3:
    • 别名模板在许多现代C++库中被大量使用。MSVC的别名模板有缺陷,这些缺陷会阻止某些库的编译,例如RangeV3。我们正在新的“rejuv”解析器上实现部分功能。新的解析树将帮助我们修复MSVC中别名模板的所有剩余错误( 范围v3 是将范围支持添加到C++标准的建议的基础。我们有一个 范围分岔v3 这在MSVC上是可行的,但它明显落后于v3主干。)
  • 预处理器:
    • 大多数代码库不使用深奥的宏,所以我们才刚刚开始主要的预处理器一致性工作。我们已经修复了在OSS库中遇到的错误,但是我们没有做出会破坏现有代码的更改。我们将在稍后的VisualStudio2017版本中引入一个opt-in开关,它将允许您使用一个一致的预处理器,该预处理器不再支持许多代码库中存在的一些旧MSVC ISM。
  • 一如既往,在 开发者社区门户 将被视为和响应的Visual C++团队。

功能状态表

以下是Stephan T准备的特性状态表和注释。Lavavej(没有通常的颜色突出显示)。

C++ 11/14核心语言特点 状态 纸类 笔记
[其他一切] VS 2017年 [抛出()]
两阶段名称查找 与2017年15.7 [两阶段]
表达SFINAE 与2017年15.7 N2634型 [解释]
C99预处理器 部分 1653号 [预处理器]
C++ 17核心语言特点 状态 纸类 笔记
删除三角图 与2010年相比 N4086型 [14]
带大括号的自动初始化列表的新规则 与2015年相比 编号3922 [14]
模板参数中的typename 与2015年相比 N4051号 [14]
名称空间和枚举数的属性 与2015年相比 N4266号 [14]
u8字符文本 与2015年相比 编号4267 [14]
忽略无法识别的属性 与2015年相比 P0283R2型 [14]
嵌套命名空间定义 与2015.3相比 N4230型
简洁的静态断言 VS 2017年 编号3928
基于广义范围的for循环 VS 2017年 P0184R0型 [14]
[[fallthrough]]属性 VS 2017年 P0188R1型
删除register关键字 与2017年15.3 P0001R1型
删除bool的运算符++ 与2017年15.3 P0002R1型
按价值捕获 与2017年15.3 P0018R3型
不重复地使用属性名称空间 与2017年15.3 P0028R4型
__你是否包括 与2017年15.3 P0061R1型 [14]
整数固定枚举的直接列表初始化 与2017年15.3 P0138R2型
constexpr lambdas公司 与2017年15.3 P0170R1型
[[nodiscard]]属性 与2017年15.3 P0189R1型
[[maybeu unused]]属性 与2017年15.3 P0212R1型
结构化绑定 与2017年15.3 P0217R3型
constexpr if语句 与2017年15.3 P0292R2型 [ifConstexpr]
带初始值设定项的选择语句 与2017年15.3 P0305R1型
允许更多非类型模板参数 与2017年15.5 N4268号
折叠表达式 与2017年15.5 N4295型 和P0036R0
删除动态异常规范 与2017年15.5 P0003R5型
向类型系统添加noexcept 与2017年15.5 P0012R1型
过对齐动态内存分配 与2017年15.5 P0035R4型
十六进制浮点文字 与2017年15.5 P0245R1型
内联变量 与2017年15.5 P0386R2型
将模板参数与兼容参数匹配 与2017年15.5 P0522R0型
保证副本省略 与2017年15.6 P0135R1型
确定资格转换 与2017年15.7 N4261号
扩展聚合初始化 与2017年15.7 P0017R1型
类模板参数推导 与2017年15.7 P0091R3型 和P0512R0
用auto声明非类型模板参数 与2017年15.7 P0127R2型
重写继承构造函数 与2017年15.7 P0136R1型
标准::流槽() 与2017年15.7 P0137R1型 [流槽]
优化表达式求值顺序 与2017年15.7 P0145R3型 和P0400R0
使用声明打包扩展 与2017年15.7 P0195R2型
修复初始化器列表构造函数的类模板参数推导 与2017年15.7 P0702R1型 [医生]
简化隐式lambda捕获 P0588R1型 [医生]
CWG1581:何时定义constexpr成员函数? P0859R0型 [医生]
放宽结构化绑定自定义点查找规则 P0961R1型 [医生]
放宽循环自定义点查找规则的范围 P0962R1型 [医生]
允许结构化绑定到可访问的成员 P0969R0型 [医生]
状态 标准 纸类 职务 笔记
部分15.7 C++ 17 P0067R5型 基本字符串转换 [字符转换]
与2017年15.7 C++ 20 P0777R1型 避免不必要的腐烂 [14]
与2017年15.7 C++ 17 P0024R2型 并行算法 [平行]
与2017年15.7 C++ 17 P0030R1型 下压(x,y,z)
与2017年15.7 C++ 17 P0218R1型 <文件系统>
与2017年15.7 C++ 17 P0219R1型 文件系统的相对路径
与2017年15.7 C++ 17 P0226R1型 数学特殊函数
与2017年15.7 C++ 17 P0317R1型 文件系统的目录项缓存
与2017年15.7 C++ 17 P0336R1型 重命名并行执行策略
与2017年15.7 C++ 17 P0392R0型 支持文件系统路径中的字符串视图
与2017年15.7 C++ 17 P0394R4型 对于异常,并行算法应该终止()
与2017年15.7 C++ 17 P0426R1型 字符特征的constexpr
与2017年15.7 C++ 17 P0430R2型 支持非POSIX文件系统
与2017年15.7 C++ 17 P0433R2型 STL的扣减指南
与2017年15.7 C++ 17 P0452R1型 统一并行算法
与2017年15.7 C++ 17 P0492R2型 解析文件系统的NB注释
与2017年15.7 C++ 17 P0682R1型 修复基本字符串转换 [医生]
与2017年15.6 C++ 17 <内存资源>
与2017年15.6 C++ 17 P0220R1型 图书馆基础V1
与2017年15.6 C++ 17 P0337R0型 删除多态分配程序分配
与2017年15.6 C++ 17 P0739R0型 STL类模板参数推导的改进 [医生]
与2017年15.5 C++ 17 P0003R5型 删除动态异常规范 [雷姆]
与2017年15.5 C++ 17 P0005R4型 不是u fn() [折旧]
与2017年15.5 C++ 17 P0033R1型 重新编写启用u共享u [14]
与2017年15.5 C++ 17 P0083R3型 拼接地图和集合
与2017年15.5 C++ 17 P0174R2型 废弃库零件 [折旧]
与2017年15.5 C++ 17 P0302R1型 正在删除std::函数中的分配器支持 [雷姆]
与2017年15.5 C++ 17 P0358R1型 修复notu fn()
与2017年15.5 C++ 17 P0414R2型 共享的u ptr,共享的u ptr [14]
与2017年15.5 C++ 17 P0497R0型 修复阵列的共享u ptr [14]
与2017年15.5 C++ 17 P0508R0型 澄清插入返回类型
与2017年15.5 C++ 17 P0521R0型 正在弃用共享的u ptr::unique() [折旧]
与2017年15.5 C++ 17 P0607R0型 STL的内联变量
与2017年15.5 C++ 17 P0618R0型 弃用 [折旧]
与2017年15.3 C++ 20 P0858R0型 Constexpr迭代器要求 [17]
与2017年15.3 C++ 17 Boyer Moore搜索()
与2017年15.3 C++ 17 P0031R0型 的constexpr
与2017年15.3 C++ 17 P0040R3型 扩展内存管理工具
与2017年15.3 C++ 17 P0084R2型 安放返回类型
与2017年15.3 C++ 17 P0152R1型 原子::锁总是空闲的吗
与2017年15.3 C++ 17 P0154R1型 硬件、破坏性干扰、尺寸等。
与2017年15.3 C++ 17 P0156R2型 作用域锁定
与2017年15.3 C++ 17 P0253R1型 修复搜索者返回类型
与2017年15.3 C++ 17 P0258R2型 具有唯一的对象表示
与2017年15.3 C++ 17 P0295R0型 gcd(),lcm()
与2017年15.3 C++ 17 P0298R3 标准::字节 [字节]
与2017年15.3 C++ 17 P0403R1型 的UDL(“meow”sv等)
与2017年15.3 C++ 17 P0418R2型 原子比较交换内存顺序要求 [14]
与2017年15.3 C++ 17 P0435R1型 检修普通型 [14]
与2017年15.3 C++ 17 P0505R0型 的constexpr(再次)
与2017年15.3 C++ 17 P0513R0型 中毒杂凑 [14]
与2017年15.3 C++ 17 P0516R0型 将共享复制标记为无例外 [14]
与2017年15.3 C++ 17 P0517R0型 从futureu errc构造futureu error [14]
与2017年15.3 C++ 17 P0548R1型 调整常用类型和持续时间 [14]
与2017年15.3 C++ 17 P0558R1型 解决原子命名基类不一致 [原子][14]
与2017年15.3 C++ 17 P0599R1型 noexcept哈希 [14]
与2017年15.3 C++ 17 P0604R0型 调用u结果,is u invocable,is u nothrow u invocable [折旧]
VS 2017年 C++ 17 <算法>样本()
VS 2017年 C++ 17 <任何>
VS 2017年 C++ 17 <可选>
VS 2017年 C++ 17
VS 2017年 C++ 17 apply()
VS 2017年 C++ 17 P0032R3型 变体/任意/可选的同质接口
VS 2017年 C++ 17 P0077R2型 是可调用的,不是可调用的吗
VS 2017年 C++ 17 P0088R3型 <变体>
VS 2017年 C++ 17 P0163R0型 共享u ptr::弱u类型
VS 2017年 C++ 17 P0209R2型 从u tuple()生成u
VS 2017年 C++ 17 P0254R2型 集成字符串视图和std::string
VS 2017年 C++ 17 P0307R2型 使可选的更大的值再次相等
VS 2017年 C++ 17 P0393R3型 使变量更大相等
VS 2017年 C++ 17 P0504R0型 重访地点/地点类型/地点索引
VS 2017年 C++ 17 P0510R0型 拒绝Nothing、数组、引用和不完整类型的变体
与2015.3相比 C++ 17 P0025R1型 夹紧()
与2015.3相比 C++ 17 P0185R1型 是可交换的,不是可交换的吗
与2015.3相比 C++ 17 P0272R1型 非常量基本字符串::data()
与2015.2相比 C++ 17 N4387号 改进成对和元组 [14]
与2015.2相比 C++ 17 N4508型 共享的u互斥体(未命名) [14]
与2015.2相比 C++ 17 P0004R1型 删除不推荐使用的Iostreams别名 [雷姆]
与2015.2相比 C++ 17 P0006R0型 类型特征的变量模板(是否相同等) [14]
与2015.2相比 C++ 17 P0007R1型 作为常量() [14]
与2015.2相比 C++ 17 P0013R1型 逻辑运算符类型特征(连词等) [14]
与2015.2相比 C++ 17 P0074R0型 所有者减少<> [14]
与2015.2相比 C++ 17 P0092R1型 地板(),天花板(),圆形(),abs() [14]
与2015.2相比 C++ 17 P0156R0型 可变锁护板 [14]
与2015年相比 C++ 17 编号3911 无效 [14]
与2015年相比 C++ 17 N4089型 独特的安全转换 [14]
与2015年相比 C++ 17 N4169号 调用() [14]
与2015年相比 C++ 17 N4190型 正在删除autou ptr、randomu shuffle()和旧的内容 [雷姆]
与2015年相比 C++ 17 4258号 无异常清理 [14]
与2015年相比 C++ 17 4259号 未捕获的异常() [14]
与2015年相比 C++ 17 编号4277 普通可复制的引用u包装 [14]
与2015年相比 C++ 17 编号4279 为映射/无序映射插入u或u assign()/尝试u emplace() [14]
与2015年相比 C++ 17 N4280型 size(),empty(),data() [14]
与2015年相比 C++ 17 N4366号 精确约束唯一的ptr分配 [14]
与2015年相比 C++ 17 N4389号 布尔常数 [14]
与2015年相比 C++ 17 P0063R3型 C11标准库 [C11][14号]
与2013年相比 C++ 17 N4510型 支持向量/列表/转发列表中的不完整类型 [14]
与2010年相比 C++ 20 P0809R0型 比较无序容器 [14]
  • C++ 20: 在C++ 20之前,我们正在努力完成C++ 17,所以尚未实现C++ 20的特性没有在这些表中列出。在STL中,“17早于20”有一些小的例外。 P0809R0型 “比较无序容器”和 P0858R0型 我们的实现已经实现了“Constexpr迭代器需求”,并且 P0777R1型 “避免不必要的衰退”纯粹是编译器吞吐量的改进。
  • 药方: 为了清楚起见,我们省略了一些不适用的文件(实现者不需要做什么,用户也不需要利用这些文件),比如措辞澄清。
  • [throw()]: 在/std:c++14 模式下,动态异常规范仍然没有实现,throw()仍然被视为uu declspec(nothrow)的同义词。在C++ 17中,动态异常规范主要通过 P0003R5型 ,留下一个痕迹:throw()已被弃用,并且必须作为noexcept的同义词。在/std:c++17 模式下,MSVC现在通过赋予throw()与noexcept相同的行为来符合标准,即通过终止来执行。编译器选项 /Zc:noexcept
© 版权声明
THE END
喜欢就支持一下吧,技术咨询可以联系QQ407933975
点赞0 分享