C++ Logo

std-proposals

Advanced search

Re: [std-proposals] vector::push_back must not invalidate past-the-end iterator

From: Sebastian Wittmeier <wittmeier_at_[hidden]>
Date: Mon, 8 Dec 2025 15:47:27 +0100
So you are saying the standard overspecified that behavior of the end iterator, as long as no new allocation happened?   Besides possibly not necessary with all implementations, what is the practical use case of allowing it?   With 'it' in this case being the previous end iterator (Or past the end? end is already 'past the end') now pointing to an element.     Trying to find use cases for not allowing it ================================   1) In theory (not 100% sure) there could be an implementation (even on x64), where any end pointer is marked (by using a bit), so that it can still be compared, but any dereference leads to a trap. Then b==e would still be true, but e could not be derenferenced, whereas b can.   2) Other possibility - perhaps too slow: All pointer arithmetics is checked. ++b checks for the current size of the underlying storage and returns  - a valid pointer, if b was not the last element and  - .end(), if it was.   -----Ursprüngliche Nachricht----- Von:Nikl Kelbon via Std-Proposals <std-proposals_at_[hidden]> Gesendet:Mo 08.12.2025 15:45 Betreff:[std-proposals] vector::push_back must not invalidate past-the-end iterator An:std-proposals <std-proposals_at_[hidden]>; CC:Nikl Kelbon <kelbonage_at_[hidden]>; The standard needs to better clarify the section on vector iterator invalidation. Why i think its important: Some implementations added checks like: "oh, we must store all .end() iterators into global map under mutex and mark them invalid on each push_back, it will be SO useful for our developers!" So, minimal example where it breaks completely: std::vector<int> v; v.reserve(10); v.push_back(1); auto b = v.begin(); auto e = v.end(); v.push_back(1); ++b; REQUIRE(b == e); // assertion failure: // _STL_VERIFY(this->_Getcont() == _Right._Getcont(), "vector iterators incompatible"); Its common pattern when using vector to reserve memory and push values, there are no "better way to do it", thats why it must be valid Now about standard: here's a quote from the standard regarding append_range and, apparently, push_back (https://eel.is/c++draft/vector#modifiers-2):  If no reallocation happens, then references, pointers, and iterators before the insertion point remain valid but those at or after the insertion point, including the past-the-end iterator, are invalidated   It explicitly states that despite there are no relocation happen, the past-the-end iterator is invalidated, although there's no reason for a vector to be so. Yes, a past-the-end iterator will no longer be past-the-end, but that doesn't make it invalid. In any implementation, even a foolish one, it's hard to imagine how, without relocation, this iterator could become anything other than just an iterator to the last element of the vector. I think in this case standard should separate invalidation and what happens here - its not invalidation rly.   -- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2025-12-08 15:02:08