这是未定义的行为吗?
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规范中的部分,它描述了向量的下标运算符必须在小于(而不是小于或等于)的值上调用尺寸,反之亦然?
由于
答案 0 :(得分:6)
是的,这些程序片段有不确定的行为。
表101将test[0]
定义为*(test.begin() + 0)
,如果您没有元素,则无效:
[C++11: 24.2.1/5]:
正如指向数组的常规指针一样,保证指针值指向数组的最后一个元素,因此对于任何迭代器类型,都有一个指向超过最后一个元素的迭代器值。相应的序列。这些值称为 past-the-end 值。定义了表达式i
的迭代器*i
的值称为 dereferenceable 。 图书馆永远不会假定过去的价值是可解除引用的。 [..]
表106列出了解除引用性作为*i
有效性的先决条件,给定任何迭代器i
。
之后您尝试接收地址并不重要:您已经破坏了您的计划。例如,对于任何过去的迭代器,您的标准库实现可以顺从地触发operator*
的断言。