微软官宣:GSL 3.0.0发布
GSL3.0.0正式发布
我们高兴地宣布:C++CoreGuidelinesSupportLibrary(GSL)的微软实现3.0.0版本已经正式可用 。 gsl::span的微软实现在C++20的span标准化进程中扮演着一个非常关键的角色 。 但是 , 标准中并没有包含用于内存边界安全的运行时检查 。 在微软的自身产品中 , gsl::span所提供的内存边界安全特性成功地避开了一些安全问题 。 这次的发布版本在继续维护内存边界安全的同时 , 还对我们的实现进行了现代化升级 , 从而和C++20span保持一致 。
有哪些更新
>新的gsl::span和gsl::span_iterator实现 , 保持与C++20标准的一致性 。
>对ContractViolation行为的更改 。
>添加CMake支持 。
>gsl::multi_span和gsl::strided_span被标记为废弃 。
在什么情况下我应该使用gsl::span , 而不是std::span?
默认情况下 , 如果你已经启用了C++20模式并且不需要内存边界运行时检查 , 则可以使用VS2019v16.6(在v16.7中 , 有一些额外的接口变更)自带的std::span 。 如果你需要支持C++20以下的版本(gsl::span支持C++14及以上)或者需要内存边界运行时检查(所有执行在gsl::span上的操作和它的迭代器都会有显式的边界安全检查) 。
gsl::span
随着对span的标准化即将完成 , 我们决定是时候将我们的实现保持和标准设计一致了 。 在新的实现中提供了全功能的边界检查 , 确保了当底层数据有效时的边界安全 。
主要的修改要点
gsl::span被重新实现主要是为了和标准的std::span保持一致 。 最大的变化是span的大小现在被定义为了无符号整数类型 。 之前我们使用的是std::ptrdiff_t这个类型 , 在新的实现中 , 我们改用了std::size_t来表示 。 另外对于它的扩展来说 , dynamic_extent现在被定义为static_cast(-1) , 而不是之前的-1 。
>span::size_type取代了原有的span::index_type 。
>添加了CTAD(ClassTemplateArgumentDeduction)支持 。
接口一致性
在接口层面 , 还有如下的一些改动来保持gsl::span和std::span的一致性 。
移除的函数
>span::operator()
>span::at
>span::cbegin
>span::cend
>span::crbegin
>span::crend
新增的函数
【微软官宣:GSL 3.0.0发布】>span::front
>span::back
重命名的函数
span::as_writeable_bytes被重新命名为span::as_writable_bytes
gsl::span_iterator的修改要点
在我们对span_iterator的新版实现中 , 我们彻底地重写了全部的代码 , 使之看起来更加像一个范围(range-like) 。 在之前的实现中 , 我们使用了一个span的指针和一个偏移 , 而在新版本中 , 我们使用了三个指针 , 它们分别是:begin,end和current 。
新版实现的好处
新版实现自身可以执行所有的边界检查 , 而不是调用span 。 通过依赖指向底层数据的指针 , 而不是指向span的指针 , 新版的span_iterator可以拥有比底层span更长的生命周期 。
新的头文件<gsl/span_ext>
有些用户可能会需要依赖旧版本的span实现 , 但是这些旧版实现在span的标准版实现中已经被移除了 , 为了支持这些用户 , 我们创建了新的头文件<gls/span_ext> 。
从<gsl/span>中被删除的并加入到<gsl/span_ext>中的元素
>spancomparisonoperators
>gsl::make_span
>spanspecializationofgsl::at
>gsl::begin
>gsl::rbegin
>gsl::crbegin
>gsl::end
>gsl::rend
>gsl::crend
契约违规
契约违规不再是可配置的 。 如果发生了违规 , 都会导致程序终止运行 , 而不是像之前那样可以通过提供编译器开关来抛出异常或者忽略违规 。 不过 , 这可能在将来的实现中发生改变 。 需要注意的是 , 移除抛出异常这种行为可能会要求我们将现有的测试套件从Catch2迁移到GoogleTest , 因为GoogleTest可以在测试契约违规用例时更加容易的支持失效测试(DeathTests) 。
CMake的改进
新版实现中现已支持find_package 。 一旦新版本完成安装 , 则可以使用find_package(Microsoft.GSLCONFIG)轻松找到GSL库 。
关于multi_span和strided_span的废弃声明
为了将GSL的微软实现和C++核心规范(CoreGuidelines)更好地保持一致 , 我们决定将gsl::multi_span和gsl::strided_span的实现声明为废弃 。 虽然现在我们还是会提供这些头文件 , 但是它们将不会再进行开发和维护 , 除非C++核心规范需要它们 。
实现变更可能导致的编译失败及修复措施
变更:在gsl::span中 , 原来带符号的std::ptrdiff_t类型修改成无符号的std::size_t可能会导致带符号/无符号的不一致 。
修复措施:使用static_cast或者gsl::narrow_cast来解决这个不一致问题 。
变更:gsl::multi_span和gsl::strided_span被声明为废弃 。
修复措施:以常量引用的方式传递多维数组 , 而不是使用gsl::multi_span 。
变更:使用到了movedspan帮助函数的代码可能会产生编译错误 。 例如span比较操作符 , gsl::make_span等 。
修复措施:当你使用到这些函数的时候 , 请包含<gsl/span_ext> , 而不是<gsl/span> 。
变更:对契约违规抛出异常已经不再支持 。
修复措施:当应用程序终止运行之前 , 请使用一个终止处理例程来记录相关的诊断信息 。 对抛出异常这一行为的依赖将不再被确保是安全的 。
总结
内存越界的确是一个很容易被忽略且难以诊断的问题 , 如果善用GSL , 应该会显著的减少此类编码错误 , 进而提升产品健壮性 。

文章图片
推荐阅读
- 微软 Win10 版本 2004 正式版将在下周开启推送
- 《月上重火》正式官宣,罗云熙陈钰琪携手演绎热血侠情江湖
- 有钱任性?微软终于模拟出整个地球,地图全部加载需要7000万GB
- 微软即将实施Windows10新规!数亿用户告别
- 阴阳师:阴阳师官宣最新联动动漫,鬼灭之刃的粉丝们有“福”了
- 混合现实 MR 浏览器 Firefox Reality 登陆微软 Windows 10 商店
- 超级大福利!Epic官宣本周免费赠送《GTA5》
- 王者荣耀:奇怪的CP又增加了,曜和西施就差官宣,而这一对超乎你想象!
- 微软:将在2021年合并Win10 IoT核心版和物联网企业版
- 疫情重磅官宣!孩子在学校究竟该怎么戴口罩?空调怎么开?低风险地区最新指引来了! | 聚焦疫情
