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

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

问题描述

给定 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中的未定义行为这样的溢出问题: 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< int *> :: 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 -th元素,则表达式(P )+ N 等价, N +(P))和(P)-N (其中 N 的值 n 分别指向 i + n -th和 i - n - 数组对象的元素,只要它们存在即可。此外,如果表达式 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.

未初始化的指针不是一回事,因为你从未做过任何事情那个指针,除了声明它(显然是有效的)。但是你甚至无法评估它(不是取消引用— 评估),而不会给程序带来未定义的行为。直到你为它指定了一个有效值。

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 past-the-end迭代器/指针,它是有效的(例如 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天全站免登陆