非解除引用的迭代器是否超过了“最后一个"?数组未定义行为的迭代器? [英] Are non dereferenced iterators past the "one past-the-end" iterator of an array undefined behavior?

查看:18
本文介绍了非解除引用的迭代器是否超过了“最后一个"?数组未定义行为的迭代器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Given int foo[] = {0, 1, 2, 3}; 我想知道指向最后一个"的迭代器是否无效.例如:auto bar = cend(foo) + 1;

Given int foo[] = {0, 1, 2, 3}; I want to know if iterators that point past the "one past-the-end" are invalid. For example: auto bar = cend(foo) + 1;

在 Stack Overflow 问题中,有大量投诉和警告称这是未定义的行为",如下所示:c++ 当过去结束迭代器时迭代器 + 整数的结果是什么? 不幸的是,唯一的来源是挥手.

There are a ton of complaints and warnings that this is "undefined behavior" in Stack Overflow questions like this: c++ what's the result of iterator + integer when past-end-iterator? Unfortunately the only source is hand waving.

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

I'm having more and more trouble buying that, for example:

int* bar;

未初始化,但肯定不会调用未定义的行为,并且经过足够的尝试,我确信我可以找到一个实例,其中此未初始化的 bar 中的值与 cend 具有相同的值(foo) + 1.

Is uninitialized, but certainly does not invoke undefined behavior, and given enough tries I'm sure I could find an instance where the value in this uninitialized bar had the same value as cend(foo) + 1.

这里最大的困惑之一是我不是询问取消引用cend(foo) + 1.我知道这将是未定义的行为,标准禁止这样做.但答案如下:https://stackoverflow.com/a/33675281/2642059 仅引用取消引用此类迭代器是非法的回答问题.

One of the big confusions here is that I am not asking about dereferencing cend(foo) + 1. I know that would be undefined behavior and the standard forbids it. But answers like this: https://stackoverflow.com/a/33675281/2642059 which cite only that dereferencing such an iterator is illegal do not answer the question.

我也知道 C++ 只保证 cend(foo) 将是有效的,但它可能是 numeric_limits::max(),在在这种情况下 cend(foo) + 1 会溢出.我对这种情况不感兴趣,除非它在标准中被称为我们不能让迭代器超过最后一个"的原因.我知道 int* 实际上只是保存一个整数值,因此可能会溢出.

I also know that C++ only guarantees that cend(foo) will be valid, but it could be numeric_limits<int*>::max(), in which case cend(foo) + 1 would overflow. I'm not interested in that case unless it is called out in the standard as the reason we can't have an iterator past the "one past-the-end". I know that int* really just holds an integer value, and as such is subject to overflow.

我想要一个可靠来源的引文,指出将迭代器移到最后一个"元素之外是未定义的行为.

推荐答案

是的,如果你形成这样的指针,你的程序就会有未定义的行为.

Yes, your program has undefined behaviour if you form such a pointer.

那是因为你唯一能做的就是增加一个有效指针,使其越过它指向的对象的边界,这是一个未定义的操作.

That's because the only way you can do so is to increment a valid pointer past the bounds of the object it points inside, and that is an undefined operation.

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

[C++14: 5.7/5]: When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integral expression. In other words, if the expression P points to the i-th element of an array object, the expressions (P)+N equivalently, N+(P)) and (P)-N (where N has the value n) point to, respectively, the i + n-th and i − n-th elements of the array object, provided they exist. Moreover, if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one past the last element of an array object, the expression (Q)-1 points to the last element of the array object. If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

未初始化的指针不是一回事,因为除了声明它(这显然是有效的)之外,您从未做过任何事情来获取"该指针.但是你甚至不能在不给你的程序注入未定义行为的情况下评估它(不是取消引用 —evaluate).除非您为其分配了有效值.

An uninitialised pointer is not the same thing because you never did anything to "get" that pointer, other than declaring it (which is obviously valid). But you can't even evaluate it (not dereference — evaluate) without imbuing your program with undefined behaviour. Not until you've assigned it a valid value.

作为旁注,我不会称这些越过终点"迭代器/指针,这是 C++ 中的一个术语,它特指one 越过终点"迭代器/指针,这是有效的(例如 cend(foo) 本身).你已经waaaay 过了终点.;)

As a sidenote, I would not call these "past-the-end" iterators/pointers, a term in C++ which specifically means the "one past-the-end" iterator/pointer, which is valid (e.g. cend(foo) itself). You're waaaay past the end. ;)

这篇关于非解除引用的迭代器是否超过了“最后一个"?数组未定义行为的迭代器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆