为什么std::span::operator[] 在越界访问时被明确规定为未定义行为?

编程语言 2026-07-09

受到 这个问题 的启发,我在阅读关于通过 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 >= sizes[index] 为未定义,为实现提供了机会。在调试构建中,可以生成有用的诊断。自C++26起,在强化实现中越出span的边界会触发契约违规。实现所采取的任何此类措施并不需要关心实际是否存在元素,即 data()[index] 是否有效,因为在越出span的边界时,operator[] 已被明确标记为未定义。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章