Topic: MSVC 5.0 STL list::const_iterator error??


Author: "Mark Sebern" <msebern@nospam.sebern.com>
Date: 1998/01/12
Raw View
In the MSVC 5.0 version of the STL (Plauger?), the list::const_iterator
class is derived from the list::iterator base class. Thus it seems that a
const_iterator value can be assigned (by object slicing) to a non-const
iterator object. The non-const iterator can then be used to modify an
object stored in a const list. Somehow this does not seem like the correct
behavior to me. Can anyone confirm that this behavior is contrary to the
draft ANSI standard?

Example follows.

// testlistiter
#include <list>
#include <iostream>

using namespace std;

void foo (const list<int>& list_arg);
void main ()
{
 list<int> list_int;

 list_int.push_back (10);
 foo (list_int);

 cout << (*(list_int.begin())) << endl;
}

void foo (const list<int>& list_arg)
{
 list<int>::iterator iter;
 iter = list_arg.begin();
 (*iter) = 99;
}

-- Mark Sebern (remove "nospam" from email address)
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/01/13
Raw View
Mark Sebern <msebern@nospam.sebern.com> wrote:
: In the MSVC 5.0 version of the STL (Plauger?), the list::const_iterator
: class is derived from the list::iterator base class. Thus it seems that a
: const_iterator value can be assigned (by object slicing) to a non-const
: iterator object. The non-const iterator can then be used to modify an
: object stored in a const list.

Hmm.... Microsoft is not known for writing decent code, but if
what you are saying is correct, that's plain outrageous.

1. list::const_iterator IS_NOT_A list::iterator by any stretch
   of imagination. If anything, it more like the other way around,
   but not quite. It might be that list::const_iterator
   IS_IMPLMENTED_IN_TERMS_OF list::iterator, which you can express
   by private inheritance, but you seem to imply that the inheritance
   is public <shrug>.

2. If they derive from list::iterator, it must have a virtual
   destructor. This would introduce an unacceptable (for stdlib)
   overhead, since iterators are designed to be passed by value
   a lot, and normally they are nothing more then wrappers around
   a single pointer.

: Somehow this does not seem like the correct
: behavior to me. Can anyone confirm that this behavior is contrary to the
: draft ANSI standard?

Hmm... Up until recently there even was no requirement that an
iterator is convertible to const_iterator. It was introduced
lately, but the appropriate draft standard is not available
to the public. Now that you've mentioned it, I realized that
there should have also been a requirement that there is
no (at least implicit) conversion from const_iterator
to iterator. Is it there, anyone? Something tells me that not.
If my fears are correct, then MS implementation is compliant <shrug>.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Martin Connell <martinc@topology-com.UCAR.EDU>
Date: 1998/01/14
Raw View
You may have a good point there.  It looks to me that Plauger meant,
perhaps, for const_iterator to inherit privately from iterator.  However, a
quick grep shows he's been consistent across all this container classes.

Have you tried mailing this to the Plauger himself?

Martin
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Matt Austern <austern@isolde.mti.sgi.com>
Date: 1998/01/14
Raw View
Oleg Zabluda <zabluda@math.psu.edu> writes:

> Hmm... Up until recently there even was no requirement that an
> iterator is convertible to const_iterator. It was introduced
> lately, but the appropriate draft standard is not available
> to the public. Now that you've mentioned it, I realized that
> there should have also been a requirement that there is
> no (at least implicit) conversion from const_iterator
> to iterator. Is it there, anyone? Something tells me that not.
> If my fears are correct, then MS implementation is compliant <shrug>.

There is no such requirement, no.  All of the generic requirements in
the standard are phrased in terms of valid expressions.  (That is,
they list operations that you can perform.)  None of them list
operations that you can't perform.

And, in fact, that's appropriate: there is one special case where it
is correct for a container's const_iterator type to be convertible to
its iterator type.  There are two containers in the standard where,
even though the standard doesn't quite require it, I would almost
certainly expect const_iterator to be convertible to iterator.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/01/14
Raw View
Matt Austern <austern@isolde.mti.sgi.com> wrote:
: Oleg Zabluda <zabluda@math.psu.edu> writes:

: > Hmm... Up until recently there even was no requirement that an
: > iterator is convertible to const_iterator. It was introduced
: > lately, but the appropriate draft standard is not available
: > to the public. Now that you've mentioned it, I realized that
: > there should have also been a requirement that there is
: > no (at least implicit) conversion from const_iterator
: > to iterator. Is it there, anyone? Something tells me that not.
: > If my fears are correct, then MS implementation is compliant <shrug>.

: There is no such requirement, no.  All of the generic requirements in
: the standard are phrased in terms of valid expressions.  (That is,
: they list operations that you can perform.)  None of them list
: operations that you can't perform.

Not quite true. For example the standard says that the
following can't be performed:

const int v[10];
const int * cptr = &v[0];
      int *  ptr = cptr;

It should say that the following is illegal as well:

vector<int> v(10);
vector<int>::const_iterator ci = v.begin();
vector<int>::      iterator  i = ci;

: And, in fact, that's appropriate: there is one special case where it
: is correct for a container's const_iterator type to be convertible to
: its iterator type.  There are two containers in the standard where,
: even though the standard doesn't quite require it, I would almost
: certainly expect const_iterator to be convertible to iterator.

Well, for those two (set and multiset) it should be mandated as well.
The only reason iterator exists to begin with is for the compatibilty
with the interfaces of other containers. Absense of the conversion
is a part of that interface too.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Mark Sebern" <msebern@nospam.sebern.com>
Date: 1998/01/14
Raw View
Martin Connell <martinc@topology-com.UCAR.EDU> wrote in article
<69gqsb$e34$2@plug.news.pipex.net>...
> You may have a good point there.  It looks to me that Plauger meant,
> perhaps, for const_iterator to inherit privately from iterator.  However,
a
> quick grep shows he's been consistent across all this container classes.
>
> Have you tried mailing this to the Plauger himself?

No, I haven't looked for an email address for him yet. I got a pretty
dismal response from MSVC technical support, but I asked them to escalate
it to someone who knew something about the ANSI standard and the STL.

In V4.2, the list::sort member function sorted backwards, and they didn't
believe me when I told them it was wrong (until later they said, fixed in
5.0). I thought that was about as bad as it could get, but I was wrong, I
guess.

In the current case, I certainly hope the standard does not permit
assigning a const_iterator to an iterator object, as this seems to
completely defeat the purpose of the distinction between them.

If you have an email address for Plauger, I'd be glad to forward my example
and question to him.

-- Mark Sebern
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Matt Austern <austern@isolde.mti.sgi.com>
Date: 1998/01/15
Raw View
Oleg Zabluda <zabluda@math.psu.edu> writes:

> : There is no such requirement, no.  All of the generic requirements in
> : the standard are phrased in terms of valid expressions.  (That is,
> : they list operations that you can perform.)  None of them list
> : operations that you can't perform.
>
> Not quite true. For example the standard says that the
> following can't be performed:
>
> const int v[10];
> const int * cptr = &v[0];
>       int *  ptr = cptr;

But it doesn't say that as part of a generic requirement.  The fact
that you can't perform that conversion isn't stated in the generic
Random Access Iterator requirements, but in the portion of the
standard that talks about one specific kind of Random Access Iterator,
that is pointers.

As a rule the generic requirements in the standard talk about what you
can do, as opposed to what you can't do.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/01/15
Raw View
Mark Sebern wrote:
>
> In the MSVC 5.0 version of the STL (Plauger?), the list::const_iterator
> class is derived from the list::iterator base class.

I don't believe it's non conforming, but one has to be dumb
to inherit one of {T::const_iterator, T::iterator} from the
other and Plauger is usually considered a serious implementor.
All list::iterators member functions are trivials, and faster
than a function call so they should be inline. So
public inheritance make no sense for code sharing.
Also if you want to write the code once, you can do
that but without inheritance. Pretending that
T::const_iterator IS-A T::iterator or that T::iterator IS-A
T::const_iterator is nonsense. Implementing list like that
is either an intentional trap or completely silly.

Use SGI-STL, or the STLport if you can't compile SGI-STL.

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/01/15
Raw View
Matt Austern <austern@isolde.mti.sgi.com> wrote:
: Oleg Zabluda <zabluda@math.psu.edu> writes:

: > : There is no such requirement, no.  All of the generic requirements in
: > : the standard are phrased in terms of valid expressions.  (That is,
: > : they list operations that you can perform.)  None of them list
: > : operations that you can't perform.
: >
: > Not quite true. For example the standard says that the
: > following can't be performed:
: >
: > const int v[10];
: > const int * cptr = &v[0];
: >       int *  ptr = cptr;

: But it doesn't say that as part of a generic requirement.  The fact
: that you can't perform that conversion isn't stated in the generic
: Random Access Iterator requirements, but in the portion of the
: standard that talks about one specific kind of Random Access Iterator,
: that is pointers.

: As a rule the generic requirements in the standard talk about what you
: can do, as opposed to what you can't do.

Why bother introducing const_iterators at all then? It's exactly
about what you can't do. Everything you can do, is
already described in iterator.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Mark Sebern" <msebern@nospam.sebern.com>
Date: 1998/01/16
Raw View
Microsoft now acknowledges the defect, and says they are looking at ways to
fix it in the next release. Thanks to all for your comments, though I'm
still not sure about whether this obvious (to me at least) defect is
specifically forbidden by the C++ standard.

-- Mark Sebern

Valentin Bonnard <bonnardv@pratique.fr> wrote in article
<34BA35EC.775C@pratique.fr>...
> Mark Sebern wrote:
> >
> > In the MSVC 5.0 version of the STL (Plauger?), the list::const_iterator
> > class is derived from the list::iterator base class.
>
> I don't believe it's non conforming, but one has to be dumb
> to inherit one of {T::const_iterator, T::iterator} from the
> other and Plauger is usually considered a serious implementor.
[snip]
> Use SGI-STL, or the STLport if you can't compile SGI-STL.
>
> Valentin Bonnard                mailto:bonnardv@pratique.fr

---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Brock" <peabody@npcinternational.com>
Date: 1998/01/16
Raw View
Mark Sebern wrote in message <69k2ib$c47@newsops.execpc.com>...
<<
>If you have an email address for Plauger, I'd be glad to forward my example
>and question to him.
>
>-- Mark Sebern

>From an old CUJ...

pjp@plauger.com
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]