Boost logo

Boost :

From: Tom Widmer (tom_usenet_at_[hidden])
Date: 2004-03-02 05:28:16


On Mon, 1 Mar 2004 21:39:39 -0600, Shannon Stewman <stew_at_[hidden]>
wrote:

>I sent this a couple days ago, but I think it became lost in the ether
>when the list moved machines.... apologies if it didn't.
>
>
>I noticed a small potential problem with indirect_iterator. I've been
>using it with raw pointers, and the default constructor appears broken
>in this case (gcc-3.3.2):
>
> #include <boost/iterator/indirect_iterator.hpp>
> #include <iostream>
>
> struct MyType {};
> typedef MyType* MyTypeList;
> typedef boost::indirect_iterator< MyTypeList, MyType > Iter;
>
> int main( int argc, char** argv )
> {
> std::cout << "Iter() == Iter() ? "
> << ( Iter() == Iter() ) << std::endl

That's UB - uninitialized iterators (and in this case pointers) can't
be compared.

> << "Iter(NULL) == Iter(NULL) ? "
> << ( Iter(NULL) == Iter(NULL) ) << std::endl;
> }
>
>The output is:
>
> Iter() == Iter() ? 0
> Iter(NULL) == Iter(NULL) ? 1
>
>Is this an actual bug, or am I misusing the code?

(Almost) all iterators must be initialized. I think the only standard
iterators with a well defined default state are the stream iterators.
Many iterator types have no "default" state - what is an iterator
pointing to when in this default state? What container is it
associated with? It is an invalid iterator, so you can't do anything
with it anyway (including comparing it to another iterator). e.g. if I
had a debug vector iterator, I might do:

iterator()
  :p(0)
{
}
//...
bool operator==(iterator lhs, iterator rhs)
{
  assert (lhs.p != 0);
  assert (rhs.p != 0);
  return lhs.p == rhs.p;
}

>If I'm misusing the code, is there some reason for this? It's
>inconvenient that the default constructor doesn't initialize pointers
>to some consistent value; the problem goes away when I change the
>indirect_iterator default constructor:
>
> 94c94,96
> < indirect_iterator() {}
> ---
> > indirect_iterator()
> > : super_t( Iterator() )
> > {}

That gives you a false sense of safety. Default initializing many
iterator types is a no-op - they are still unusable (e.g.
std::list::iterator).

Tom

-- 
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk