Jump to content

  • Log In with Google      Sign In   
  • Create Account

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


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 Daniel E   Members   -  Reputation: 224

Like
0Likes
Like

Posted 07 January 2013 - 05:13 PM

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...


Edited by Daniel E, 07 January 2013 - 05:14 PM.


Sponsor:

#2 ApochPiQ   Moderators   -  Reputation: 16401

Like
0Likes
Like

Posted 07 January 2013 - 05:30 PM

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.



#3 SiCrane   Moderators   -  Reputation: 9670

Like
1Likes
Like

Posted 07 January 2013 - 06:47 PM

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().

#4 Bregma   Crossbones+   -  Reputation: 5469

Like
2Likes
Like

Posted 07 January 2013 - 08:30 PM

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

#5 Daniel E   Members   -  Reputation: 224

Like
0Likes
Like

Posted 08 January 2013 - 12:07 PM

Ok, thanks for clarification. Rewrote the affected code.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS