1

Suppose I've an empty list L. Currently if I run L.front(), it will merrily execute returning a garbage value. Is there some option I can turn on such that executing this would throw an exception or result in an assertion failure?

Thanks

Opt
  • 4,774
  • 3
  • 28
  • 28
  • 1
    It depends on STL implementation you are using. Please provide some more details. –  Jun 16 '11 at 21:03
  • g++ 4..6. I've accepted kert's answer as it provides details for both MSVC and g++ – Opt Jun 17 '11 at 21:57

4 Answers4

2

Use empty() to check if the list is empty. size() is not good here because it could have linear runtime. See more details in Effective STL. empty() has constant runtime and it is a standard way.

Naszta
  • 7,560
  • 2
  • 33
  • 49
2

GCC STL checked iterators

MSVC checked iterators ( on by default )

STLPort debug mode, with checked iterators

Previous question on the same subject

Community
  • 1
  • 1
kert
  • 2,161
  • 21
  • 22
  • Regarding MSVC, they're on by default for debug builds. For release builds, they're off by default in VC++ 2010 and on by default in VC++ 2008 and 2005. – ildjarn Jun 16 '11 at 21:24
1

If you are using Visual C++ 2010 (and probably earlier versions) then you can enable secure SCL and iterator debugging by using these two macros:

#define _SECURE_SCL 1
#define _HAS_ITERATOR_DEBUGGING 1

The other standard libraries may have that too.

Edit: Just as has been suggested, there is a single macro in VC2010, that is _ITERATOR_DEBUG_LEVEL which has 3 levels defined like this:

#if _HAS_ITERATOR_DEBUGGING
    #define _ITERATOR_DEBUG_LEVEL 2
#elif _SECURE_SCL
    #define _ITERATOR_DEBUG_LEVEL 1
#else
    #define _ITERATOR_DEBUG_LEVEL 0
#endif
Gene Bushuyev
  • 5,512
  • 20
  • 19
  • Actually, those are the macros for VC++ 2005 and 2008. For VC++ 2010, they have been replaced by a single macro, `_ITERATOR_DEBUG_LEVEL`. (Yes, I realize MSDN doesn't mention this.) – ildjarn Jun 16 '11 at 21:14
  • 1
    Please, don't define these macros yourself. Getting them right is *hard*, [Stephen Lavavej also discourages this](http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Stephan-T-Lavavej-Advanced-STL-3-of-n). Also, VS2010 has `_ITERATOR_DEBUG_LEVEL`. In debug mode it is set to `2`, which is full debugging. you can redefine *that* macro, but please let the other as they are. – Xeo Jun 16 '11 at 21:16
  • @Xeo: I don't like messing with macros, but sometimes you have to. For example, standard doesn't prohibit from evaluating invalid iterators as long as they are not used, so `&*container.end();` is a perfectly good expression, but it would cause VC code to crash with SCL exception unless you disable it. – Gene Bushuyev Jun 16 '11 at 21:24
  • 1
    @Gene : Why would you think `&*container.end();` is valid? Dereferencing any end iterator is illegal. – ildjarn Jun 16 '11 at 21:25
  • @Gene: What @ildjarn says and *why the heck would you want to do that?!* – Xeo Jun 16 '11 at 21:25
  • @ildjarn: I don't currently have time to browse the standard, but I'm sure it does allow dereferencing as long as it is not used. @Xeo: it's quite common if you have an algorithm that, for example, takes pointers and you have only iterators, e.g. `algo(&*str.begin(), &*str.end());` – Gene Bushuyev Jun 16 '11 at 21:29
  • @Gene : No, you can't, and it's §24.1/5. If your code does this, it's wrong; if it appears to work correctly, you've just been lucky. The legal way to write that (assuming the memory underlying the iterators is contiguous, which **no** non-pointer iterator category can guarantee) is `algo(&*str.begin(), &*str.begin() + str.size());` – ildjarn Jun 16 '11 at 21:34
0

Some standard libraries do offer such an option. You'd need to consult the documentation and/or code foryour particular implementation/compiler in order to determine its characteristics and how to enable it.

Alternately you could use a memory checker like valgrind or Purify instead of doing it in the library level.

Mark B
  • 95,107
  • 10
  • 109
  • 188