限制迭代器是否有效 [英] Is clamping on iterators valid

查看:78
本文介绍了限制迭代器是否有效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在实际生产代码中发现了以下内容. 我怀疑它实际上具有未定义的行为,但是,我找不到有关cppreference的相关信息.您能否确认这是UB或有效代码,以及为什么这是UB/有效(最好带有标准引号)?

I found the following in actual production code. My suspicion is that it actually has undefined behavior into it, however, I couldn't find the related info on cppreference. Can you confirm this is UB or valid code and why this is UB/valid (preferably with a quote of the standard)?

#include <vector>

int main(int, char **)
{
    auto v = std::vector<int>({1,2,3,4,5});
    auto begin = v.begin();
    auto outOfRange = begin + 10;
    auto end = v.end();
    auto clamped = std::min(outOfRange, end);
    return (clamped == end) ? 0 : 42;
}

编译器资源管理器上的代码

如您所见,begin + 10将创建一个超出std::vector范围的迭代器. 但是,由于使用std::min进行了限制,因此未使用该迭代器.

As you can see begin + 10 will create an iterator that's out of range of the std::vector. However, that iterator ain't being used, as it is clamped using std::min.

推荐答案

根据标准

将具有整数类型的表达式添加或减去时 从指针开始,结果具有指针操作数的类型.如果 指针操作数指向数组对象的元素,并且该数组 足够大,结果指向的元素与 原始元素,使得 结果数组元素和原始数组元素等于整数表达式. 换句话说,如果表达式指向 数组对象,表达式(P)+N(等效于N+(P))(P)-N(其中N具有值n)分别指向 数组对象的i+n-thi−n-th元素,前提是它们 存在.此外,如果表达式P指向的最后一个元素 一个数组对象,表达式(P)+1指向最后一个 数组对象的元素,如果expressionQpoints指向 数组对象的最后一个元素,表达式(Q)-1指向 arrayobject的最后一个元素.如果指针操作数和 结果指向同一数组对象的元素,或 数组对象的最后一个元素,求值不应产生 溢出;否则,行为是不确定的

When an expression that has integral type is added to or subtracted from a pointer, the result has the typeof the pointer operand. If the pointer operand points to an element of an array object, and the array islarge enough, the result points to an element offset from the original element such that the difference ofthe subscripts of the resulting and original array elements equals the integral expression. In other words, if the expression points to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the valuen) point to, respectively, the i+n-th and i−n-th elements of the arrayobject, 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 expressionQpointsone past the last element of an array object, the expression (Q)-1 points to the last element of the arrayobject. 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

如果为gcc打开迭代器调试,则可以验证这一点

You can verify this if you turn on iterator debugging for gcc

# g++ main.cpp -D_GLIBCXX_DEBUG -o main
# ./main
C:/mingw-w64/i686-8.1.0-win32-dwarf-rt_v6-rev0/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/debug/safe_iterator.h:374:
Error: attempt to advance a dereferenceable (start-of-sequence) iterator 10
steps, which falls outside its valid range.

Objects involved in the operation:
    iterator @ 0x0061FE3C {
      type = __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<int*, std::__cxx1998::vector<int, std::allocator<int> > >, std::__debug::vector<int, std::allocator<int> > > (mutable iterator);
      state = dereferenceable (start-of-sequence);
      references sequence with type 'std::__debug::vector<int, std::allocator<int> >' @ 0x0061FE50
    }

这篇关于限制迭代器是否有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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