为什么std::span::operator[] 在越界访问时被明确规定为未定义行为?
受到 这个问题 的启发,我在阅读关于通过 std::span::operator[] 进行越界访问的内容,参见 这里:
如果
idx < size()是false,其行为是未定义的。(直到C++26)
为什么要明确写成未定义?
使用
std::span s{ptr,size};
我看到了两种情况:
- 底层数组只有
s.size()个元素,试图调用s[s.size()]将是未定义的,因为ptr[size]是未定义的。把span::operator[]指定为未定义其实并没有改变这一点。 - 底层数组元素超过
s.size()个。在这种情况下s.data()+size可以被解引用而不成问题,但s[s.size()]是未定义的。
为什么要将 span::operator 指定为未定义,针对那些可以通过 span::data() 访问的元素?
解决方案
一个对 operator[] 的朴素实现可以简单地返回 data()[index]。在这种情况下,当索引越界时就不需要显式地指定 operator[] 是未定义的。将指针往数组末端移动并对其进行解引用本身就是未定义的。
然而,明确指出在 index >= size 时 s[index] 为未定义,为实现提供了机会。在调试构建中,可以生成有用的诊断。自C++26起,在强化实现中越出span的边界会触发契约违规。实现所采取的任何此类措施并不需要关心实际是否存在元素,即 data()[index] 是否有效,因为在越出span的边界时,operator[] 已被明确标记为未定义。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。