Subject: Re: gdb discrepancy in c++ iterators
From: Fred Ma <[email-masked]>
To: [email-masked]
Date: Sat, 29 Mar 2003 12:38:02 -0500
Newsgroups: gnu.gcc.help,comp.unix.programmer

Igor Pechtchanski wrote:

> On Sat, 29 Mar 2003, Fred Ma wrote:
>
> > Hello,
> >
> > I'm having the following problem only on cygwin,
> > not on solaris 8.  I have a sanity-check program:
> >
> >      #include<vector>
> >      #include<iostream>
> >      using namespace std;
> >      int main(void)
> >      {
> >         vector<int> vi(3);
> >         vector<int>::iterator it_vi = vi.begin();
> >         cout << "Hello world.";
> >      }
> >
> > I compile it with gcc 3.2 use
> > gdb2003-03-03-cvs(cygwin-special) to view
> > vi.begin() and it_vi.  They are different:
> >
> >      (gdb) p vi.begin()
> >      $1 = {<iterator<std::random_access_iterator_tag,int,int,int*,int&>> =
> >                  {<No data fields>}, _M_current = 0xc7e44589}
> >      (gdb) p it_vi
> >      $2 = {<iterator<std::random_access_iterator_tag,int,int,int*,int&>> =
> >                  {<No data fields>}, _M_current = 0xa041de0}
> >
> > Why are they different?  If I actually dereference the iterators,
> > they contain the same thing.  But I want to deal with the iterators
> > themselves.  In particular, I want a conditional breakpoint to trigger
> > when it_vi==vi.begin()+4.  gdb won't let you add 4 to a random
> > access iterator, so I have to use the _M_current member data.
> > Since they are not the same above, I can't do that.  Thanks for
> > any light on why they differ.
> >
> > Fred
>
> Umm, you do know that calling vi.begin() will create a *new* iterator,
> right?  As for it working on other systems, they may have different
> implementations of STL iterators.
>         Igor

Yes, I know that.  I'm comparing it on a different system but
with the same version of gcc, so I expect the STL implementation
to be the same.  I have to qualify that; the cygwin version is
gcc3.2 20020927 (prerelease).  The solaris version is 3.2.1,
and since there is no 3.2.0 on www.gun.org, cygwin's gcc is
probably a tenative version of the solaris version.  But I don't
expect great changes, at least not as big as the definition of
_M_current.  If iterators are suped up pointers, then _M_current
is the primitive pointer that is suped up.  From the properly
functioning gcc/gdb on solaris, it_vi and vi.begin() contain the
same value for _M_current.  If I dereference _M_current in
either iterator, I get the right object value.  If I try this on cygwin,
*it_vi._M_current returns the right value, but
*(vi.begin()._M_current) is an error because the memory
location can't be accessed.  In the actual program that
I'm trying to debug, none of the changes made to a aggregate
vector elements via it_vi seem to have any effect, probably
because of the differing _M_current values (in that case,
vi.begin()._M_current is pointing to valid memory space).

About the fact that the iterators are different, gdb's print
command prints the object itself, including data members,
*not* the address of the object.  So the fact that the iterators
are different should not make the objects' value different.

Another strange "clue", if it is that:  if I print *it_vi._M_current
in the full blown program, vi.begin()_M_current actually changes
values (by itself) so as to be the same as it_vi._M_current.
Very  bizzare.

Fred

P.S.  The gdb version on cygwin (at top) is relatively
recent.  In contrast, on solaris8 (where things seem to
behave right), it's gdb 4.17, copyright 1998.

--
Fred Ma, [email-masked]
Carleton University, Dept. of Electronics
1125 Colonel By Drive, Ottawa, Ontario
Canada, K1S 5B6

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/