『微软』微软官宣:GSL 3.0.0发布


GSL 3.0.0 正式发布 我们高兴地宣布:C++ Core Guidelines Support Library (GSL)的微软实现3.0.0版本已经正式可用 。 gsl::span的微软实现在C++ 20 的span标准化进程中扮演着一个非常关键的角色 。 但是 , 标准中并没有包含用于内存边界安全的运行时检查 。 在微软的自身产品中 , gsl::span所提供的内存边界安全特性成功地避开了一些安全问题 。 这次的发布版本在继续维护内存边界安全的同时 , 还对我们的实现进行了现代化升级 , 从而和C++ 20 span保持一致 。
有哪些更新 > 新的gsl::span和gsl::span_iterator实现 , 保持与C++ 20标准的一致性 。
> 对Contract Violation行为的更改 。
> 添加CMake支持 。
> gsl::multi_span和gsl::strided_span被标记为废弃 。
在什么情况下我应该使用gsl::span , 而不是std::span? 默认情况下 , 如果你已经启用了C++ 20模式并且不需要内存边界运行时检查 , 则可以使用VS2019 v16.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(Class Template Argument Deduction)支持 。
接口一致性 在接口层面 , 还有如下的一些改动来保持gsl::span和std::span的一致性 。
移除的函数 > span::operator()
> span::at
> span::cbegin
> span::cend
> span::crbegin
> span::crend
新增的函数 > 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更长的生命周期 。
新的头文件 有些用户可能会需要依赖旧版本的span实现 , 但是这些旧版实现在span的标准版实现中已经被移除了 , 为了支持这些用户 , 我们创建了新的头文件 。
从中被删除的并加入到中的元素 > span comparison operators
> gsl::make_span
> span specialization of gsl::at
> gsl::begin
> gsl::rbegin
> gsl::crbegin
> gsl::end
> gsl::rend
> gsl::crend
契约违规 契约违规不再是可配置的 。 如果发生了违规 , 都会导致程序终止运行 , 而不是像之前那样可以通过提供编译器开关来抛出异常或者忽略违规 。 不过 , 这可能在将来的实现中发生改变 。 需要注意的是 , 移除抛出异常这种行为可能会要求我们将现有的测试套件从Catch2迁移到Google Test , 因为Google Test可以在测试契约违规用例时更加容易的支持失效测试(Death Tests) 。


推荐阅读