C++ 未取消引用的迭代器是否超过;“一过终点”;数组未定义行为的迭代器?

C++ 未取消引用的迭代器是否超过;“一过终点”;数组未定义行为的迭代器?,c++,arrays,pointers,iterator,language-lawyer,C++,Arrays,Pointers,Iterator,Language Lawyer,给定intfoo[]={0,1,2,3}我想知道指向“一过终点”的迭代器是否无效。例如:autobar=cend(foo)+1 在StackOverflow这样的问题中,有大量抱怨和警告称这是“未定义的行为”:不幸的是,唯一的来源是挥手 我越来越难以购买,例如: int* bar; 未初始化,但肯定不会调用未定义的行为,如果进行足够的尝试,我肯定可以找到一个实例,其中未初始化的条中的值与cend(foo)+1中的值相同 这里最大的困惑之一是,我不是在问取消引用cend(foo)+1我知道这是未

给定
intfoo[]={0,1,2,3}我想知道指向“一过终点”的迭代器是否无效。例如:
autobar=cend(foo)+1

在StackOverflow这样的问题中,有大量抱怨和警告称这是“未定义的行为”:不幸的是,唯一的来源是挥手

我越来越难以购买,例如:

int* bar;
未初始化,但肯定不会调用未定义的行为,如果进行足够的尝试,我肯定可以找到一个实例,其中未初始化的
条中的值与
cend(foo)+1
中的值相同

这里最大的困惑之一是,我不是在问取消引用
cend(foo)+1
我知道这是未定义的行为,标准禁止这样做。但是这样的回答:只引用取消引用这样的迭代器是非法的,这并不能回答这个问题

我还知道C++仅仅保证<代码> cEnter(FoO)< /C> >是有效的,但它可以是<代码> NoimiCimult::Max()/Cuth>,在这种情况下,代码> cEnter(FoO)+ 1 会溢出。我对这种情况不感兴趣,除非它在标准中被称为我们不能让迭代器超过“结束一个”的原因。我知道,

int*
实际上只保存一个整数值,因此会发生溢出


我想引用一个可靠的来源,将迭代器移到“结束后一个”元素之外是未定义的行为。是的,如果您形成这样的指针,您的程序具有未定义的行为

这是因为唯一可以这样做的方法是增加一个有效指针,使其超过它所指向的对象的边界,这是一个未定义的操作

[C++14:5.7/5]:
当向指针添加或从指针中减去具有整数类型的表达式时,结果具有指针操作数的类型如果指针操作数指向数组对象的某个元素,且数组足够大,则结果指向与原始元素偏移的元素,从而结果数组元素与原始数组元素的下标之差等于整数表达式。换句话说,如果表达式
P
指向数组对象的第i个元素,则表达式
(P)+N
等效地,
N+(P)
)和
(P)-N
(其中
N
的值为N)分别指向第i+N和i− 数组对象的第n个元素,前提是它们存在。此外,如果表达式
P
指向数组对象的最后一个元素,则表达式
(P)+1
指向数组对象的最后一个元素,如果表达式Q指向数组对象的最后一个元素,则表达式
(Q)-1
指向数组对象的最后一个元素如果指针操作数和结果都指向同一数组对象的元素,或超过数组对象最后一个元素的元素,则计算不应产生溢出;否则,行为未定义。

一个未初始化的指针不是一回事,因为除了声明它(这显然是有效的)之外,您从来没有做过任何事情来“获取”该指针。但是如果不给程序注入未定义的行为,您甚至无法对其进行评估(而不是取消引用-评估)。除非您为其指定了有效值

作为一个旁侧,我不称这些“过去的结束”迭代器/指针,C++中的术语,具体地指“一个过去的结束”迭代器/指针,它是有效的(例如,代码> cEnter(fo)本身)。你已经走到尽头了


我对这种情况不感兴趣,除非它在标准中被称为我们不能让迭代器超过“结束一个”的原因。我知道int*实际上只包含一个整数值,因此会发生溢出


该标准没有讨论未定义事物的原因。你已经把逻辑颠倒过来了:事实上它是未定义的,这就是实现可能将对象放在这样一个位置的原因,否则这样做会导致溢出。如果要求“结束后两个”迭代器是有效的,那么实现将不需要将对象放在可能导致此类操作溢出的地方。

正如@Random842所说:

该标准并没有将指针类型描述为在一个平坦的线性空间中,最小值和最大值之间的所有值都是有效的,就像您假设的那样

指针不假定存在于平坦的线性空间中。相反,存在有效指针和无效指针。指针上的某些操作已定义,其他操作是未定义的行为

在许多现代系统中,指针是在平坦的线性空间中实现的。即使在这些系统上,形成某些指针的不确定性也可以打开C++编译器进行一些优化;例如,
intfoo[5];bool test(int*it1){int*it2=cend(foo);返回it1TL;DR——计算迭代器超过结束迭代器是未定义的行为,因为过程中违反了先决条件


Lightness提供了权威性地涵盖指针的引用

对于迭代器,通常不禁止递增超过“end”(超过最后一个元素的一个元素),但对于大多数各种迭代器都是禁止的:

输入迭代器需求,特别是如果可取消引用,则只可增加子句,通过引用合并到前向、双向和随机访问迭代器中

输出迭代器不受约束,它们总是可以递增的