正在获取 C++11 中 std::vector::operator[](size) 未定义行为的地址

Is taking the address of std::vector::operator[](size) Undefined Behavior in C++11

本文关键字:size 未定义 地址 C++11 获取 std operator vector      更新时间:2023-10-16

这是未定义的行为吗?

ptrdiff_t one() {
   std::vector<int> test(1);
   return &test[1] - &test[0];
}

这是未定义的行为吗?

ptrdiff_t zero() {
   std::vector<int> test;
   int * end = &test[0];
   int * begin = &test[0];
   return end - begin;
}

如果其中任何一个是未定义的行为,谁能帮我找到 C++11 规范中的部分,其中描述了必须在小于(而不是小于或等于)大小的值上调用向量的下标运算符,反之亦然?

谢谢

是的,这些程序片段具有未定义的行为。

表 101 将test[0]定义为 *(test.begin() + 0) ,如果没有元素,则无效:

[C++11: 24.2.1/5]: 正如指向数组的常规指针保证有一个指针值指向数组的最后一个元素一样,对于任何迭代器类型,都有一个指向相应序列的最后一个元素的迭代器值。这些值称为"结束"值。为其定义了表达式*i的迭代器i的值称为可取消引用该库从不假定过去结束的值是可取消引用的。[..]

表106指出,在给定任何迭代器i的情况下,取消引用性是*i有效性的先决条件。

事后尝试获取地址并不重要:您已经破坏了程序。例如,标准库实现可能会合规地触发任何过去结束迭代器的operator*断言。