Skip to main content
GameDev.net gamedev.net
🔒 Locked

std::list::clear invalidates end iterator (bug?)

Started by Daniel E Jan 7, 2013 at 11:13 PM 3 replies 1.5k views
Original Post
Daniel E
Daniel E

I've just converted my project to Visual Studio 2012 and ran into a "list iterators not compatible" error.

I could reduce the problematic code to the following:


std::list test;
std::list::iterator end = test.end();
test.clear();
assert(test.end() == end); //fail

This fails in a freshly created project.

On http://www.cplusplus.com/reference/list/list/clear/ it's said that "All iterators, references and pointers related to this container are invalidated, except the end iterators."

Does anyone know if something has changed about that? This worked fine in VS2010...

ApochPiQ
ApochPiQ

IIRC this was clarified in the standards between C++03 and C++11. In C++11, it is mandated by the standard that end() is invalidated when the container is cleared in this manner. C++03 was vague on this front and different SC++L implementations have been known to act differently.

SiCrane
SiCrane
I don't think C++11 mandates end() is invalidated, but specifies it may be invalidated. I'll have to grab an official copy later to double check, but the most recent draft says clear() for sequences in general "may invalidate the pass-the-end iterator." C++98 and C++03's description of std::list::clear() states that "Invalidates only the iterators and references to the erased elements." (Emphasis in both cases added by myself.) Interestingly, this draft of C++11 maintains the same wording for std::list::clear().
Bregma
Bregma
IIRC this was clarified in the standards between C++03 and C++11. In C++11, it is mandated by the standard that end() is invalidated when the container is cleared in this manner. C++03 was vague on this front and different SC++L implementations have been known to act differently.

My copy of the current standard states in [23.3.5.4](3) "Effects: Invalidates only the iterators and references to the erased elements."

However, Table 100, Sequence container requirements, in [23.2.3] states "Destroys all elements in a. Invalidates all references, pointers, and iterators referring to the elements of a and may invalidate the past-the-end iterator."

Both specifications are normative, but I would expect the stronger language of the specific specification in [23.3.5.4] would have stronger weight than the may clause of table 100. Nevertheless, given that there is no "unless otherwise specified" clause in [23.2.3](3), an implementation might just get away with invalidating end() on list::clear() and still be conforming.

DR 1213 points out that the meaning of "invalid iterator" is underdefined.

Stephen M. Webb
Professional Free Software Developer

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.