最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Is it safe to access elements outside subrange but inside parent range? - Stack Overflow

programmeradmin0浏览0评论

Let's say I have an std::vector<int> arr of 5 elements { 1, 2, 3, 4, 5 }.

Is it safe to get a subrange from it like sub = std::span{ arr.begin() + 2, arr.end() } and dereference element at -1 like *(sub.begin() - 1)?

In terms of pointers this looks safe, but what about iterators? If this is safe for vector and span, what about list?

Let's say I have an std::vector<int> arr of 5 elements { 1, 2, 3, 4, 5 }.

Is it safe to get a subrange from it like sub = std::span{ arr.begin() + 2, arr.end() } and dereference element at -1 like *(sub.begin() - 1)?

In terms of pointers this looks safe, but what about iterators? If this is safe for vector and span, what about list?

Share Improve this question edited 10 hours ago Botje 31.3k4 gold badges34 silver badges47 bronze badges asked 10 hours ago hopeless-programmerhopeless-programmer 1,0007 silver badges21 bronze badges 2
  • 1 gsl::span asserts on out of bounds access, but the standard libraries don't do that. – Ahmed AEK Commented 10 hours ago
  • auto& two = *std::prev(std::addressof(*sub.begin())); would be safe though – Ted Lyngmo Commented 9 hours ago
Add a comment  | 

2 Answers 2

Reset to default 1

From the definition of LegacyBidirectionalIterator:

The begin iterator is not decrementable and the behavior is undefined if --container.begin() is evaluated.

And it - n is defined in terms of --, so no, this is not safe.

In terms of pointers this looks safe, but what about iterators?

This is unsafe, and it is reasonable to assume that library implementations will verify offsets to avoid them, e.g. MSV-STL when _ITERATOR_DEBUG_LEVEL is enabled.

In this case, ranges::subrange may meet your needs as long as the operation on the original iterator is safe, since it returns the original iterator-pair.

However, subscripting on a ranges::subrange may still be unsafe because its operator[] may still be aware of out-of-bounds:

auto sub = std::ranges::subrange{ v.begin() + 2, v.end() };
auto x = sub.begin()[-1]; // safe
auto y = sub[-1];         // unsafe, UB

So, in any case, even if you think it is safe, it is better not to try to access out-of-bounds elements to avoid potential undefined behavior.

发布评论

评论列表(0)

  1. 暂无评论