STL Iterator Debugging and Secure SCL
- Posted: Jun 16, 2008 at 10:28 AM
- 41,352 Views
- 10 Comments
Loading User Information from Channel 9
Something went wrong getting user information from Channel 9
Loading User Information from MSDN
Something went wrong getting user information from MSDN
Loading Visual Studio Achievements
Something went wrong getting the Visual Studio Achievements
Right click “Save as…”
The Visual C++ runtime library now detects incorrect iterator use and will assert and display a dialog box at run time. To enable debug iterator support, a program must be compiled with a debug version of a C run time library (see C Run-Time Libraries for more information).
See Checked Iterators for more information on using iterators.
The C++ standard describes which member functions cause iterators to a container to become invalid. Two examples are:
Erasing an element from a container causes iterators to the element to become invalid.
Increasing the size of a vector (push or insert) causes iterators into the vector container become invalid.
Here, VC++ Software Engineer Stephan T. Lavavej digs into the details of STL Iterator Debugging including its implementation, usage
scenarios and interesting facts you may not find anywhere else (Channel 9 goodness). Stephan is known as STL (this is his name's acronym, by coincidence or perhaps it's simply prophetic since Stephan is a passionate advocate for STL, as you will no doubt understand
after watching and listening to this conversation). Stephan also dives a bit into Secure SCL, which is part of the VC++ Safe Libraries.
Stephan does not possess a marketing bone in his body as you can tell by his commentary that's weaved into his informal presentation of advanced topics. I love this. He speaks his mind freely, though with fairness, and that's the only way to be.
Enjoy!
Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation,
please create a new thread in our Forums,
or
Contact Us and let us know.
Follow the Discussion
Oops, something didn't work.
What does this mean?
Following an item on Channel 9 allows you to watch for new content and comments that you are interested in. You need to be signed in to Channel 9 to use this feature.What does this mean?
Following an item on Channel 9 allows you to watch for new content and comments that you are interested in and view them all on your notifications page.sign up for email notifications?
And why is it a linked list that keeps track of the iterators and not a "vector"-like (dynamic array) construct?
For one thing, the C++ standard actually specifies that a vector reallocation invalidates all iterators and pointers. If VC would do otherwise, it would break the standard (this is probably because when the standard was written a lot of implementations were already around, and a lot of those used plain pointers for the vector iterators, as the video says).
Also, if this was implemented it would likely have a similar cost to what iterator debugging has. Only, now you can't turn it off for your release builds because it would change the semantics of your program. It would simply be too slow.
First things I do when creating a new project:
[littleguru]
> I wonder why the iterator is not following to the new location, when the resizing of a vector happens.
> Is that to slow or why isn't that implemented?
It would be way too expensive (both space and time). C++ is supposed to be blazingly fast, so the Standard avoids mandating anything that could be expensive. Especially when it doesn't buy anything fundamentally useful.
It would actually be more expensive than _SECURE_SCL, which is already unloved.
You can always use indices, which aren't invalidated by reallocation.
> And why is it a linked list that keeps track of the iterators and not a "vector"-like (dynamic array) construct?
_HAS_ITERATOR_DEBUGGING's singly-linked list is actually formed from the iterators themselves, which avoids performing any dynamic memory allocations. The iterators of Standard containers aren't allowed to have throwing copy ctors (23.1/10), which is exactly what dynamic memory allocations would do.
[Sven Groot]
> For one thing, the C++ standard actually specifies that a vector reallocation invalidates all iterators and pointers.
Note that the Standard's idea of invalidation is a theoretical concept. Iterators, pointers, and references can be theoretically invalidated (e.g. by vector reallocation) without being physically invalidated. For example, if we attempted and succeeded at in-place reallocation, then we wouldn't physically invalidate anything, but the Standard would still say that things have been theoretically invalidated.
> If VC would do otherwise, it would break the standard
If the Standard says that X theoretically invalidates Y, then it's conformant to make X not physically invalidate Y.
[PhrostByte]
> Raises hand as one of those C++ developers that always disables secure scl.
You have to be careful when doing this, as I mentioned in the video, if you use something like Boost.
Stephan T. Lavavej, Visual C++ Libraries Developer
We'll certainly avoid physical invalidation whenever there are performance advantages in doing so (e.g. in-place reallocation, which I'm looking at for VC10).
_HAS_ITERATOR_DEBUGGING will always complain about theoretical invalidation, and it is extremely strict. For example, if you insert-at-middle without triggering reallocation, you've theoretically invalidated all iterators beyond the inserted element. Erasing that element doesn't make those iterators theoretically valid again, but they'll be physically valid.
I love _HAS_ITERATOR_DEBUGGING. I am relieved to hear that it complains about theoretical validation too, it should. That is what debug builds are for. My experience is that for 99% the slowdown due to the STL checking is irrelevant.
Having said that, I have a few files where we would welcome the opportunity to disable it. That is because our software has some image processing, that only one or two people are interested in debugging anyway, and usually only when they're working on bugs in that portion of the code. Now, I am expecting that undefining _HAS_ITERATOR_DEBUGGING for one file will lead to ODR violations, for sure if it shares containers with other classes in the dll. I can use plain pointers, but is there no other way?
Both Charles & STL - thanks for a great interview!
If I understood correctly, a major factor that makes HAS_ITERATOR_DEBUGGING sos slow is the need to traverse the entire iterator linked list to remove a single iteratr when it is destroyed. Maybe making the list doubly-linked can accelerate that? (the added space cost seems well worth it)
Remove this comment
Remove this thread
close