Topic: Defect Report: Clearing an empty container is undefined


Author: "Ed Brey" <brey@afd.mke.etn.com>
Date: 1999/06/25
Raw View
[Moderator note:
Please don't send DR, or any post as MIME. I have removed
the HTML part. We, moderators, may reject a defect report
if it doesn't obey the rules. --vb]

For both sequences and associative containers, a.clear() has the =
semantics of erase(a.begin(),a.end()), which is undefined for an empty =
container since erase(q1,q2) requires that q1 be dereferenceable =
(23.1.1,3 and 23.1.2,7).  When the container is empty, a.begin() is not =
dereferenceable.

The requirement that q1 be unconditionally dereferenceable causes many =
operations to be intuitively undefined, of which clearing an empty =
container is probably the most dire.

Since q1 and q2 are only referenced in the range [q1, q2), and [q1, q2) =
is required to be a valid range, stating that q1 and q2 must be =
iterators or certain kinds of iterators is unnecessary.


Proposed solution:

In 23.1.1,3, change:

p and q2 denote valid iterators to a, q and q1 denote valid =
dereferenceable iterators to a, [q1, q2) denotes a valid range

to:

p denotes a valid iterator to a, q denotes a valid dereferenceable =
iterator to a, [q1, q2) denotes a valid range

[Moderator note: ...denotes a valid range into a --vb]

In 23.1.2,7, change:

p and q2 are valid iterators to a, q and q1 are valid dereferenceable =
iterators to a, [q1, q2) is a valid range

to

p is a valid iterator to a, q is a valid dereferenceable iterator to a, =
[q1, q2) is a valid range

[Moderator note: ...denotes a valid range into a --vb]
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "P.J. Plauger" <pjp@plauger.com>
Date: 1999/06/25
Raw View
Ed Brey wrote in message <7km0hf$qne4@interserv.etn.com>...
>For both sequences and associative containers, a.clear() has the =
>semantics of erase(a.begin(),a.end()), which is undefined for an empty =
>container since erase(q1,q2) requires that q1 be dereferenceable =
>(23.1.1,3 and 23.1.2,7).  When the container is empty, a.begin() is not =
>dereferenceable.

True enough, but it's also not executed since a.begin() == a.end().
Looks okay to me.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com





[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Ed Brey" <brey@afd.mke.etn.com>
Date: 1999/06/26
Raw View
P.J. Plauger <pjp@plauger.com> wrote in message
news:7kvsfk$m45$1@news.harvard.net...
>
> Ed Brey wrote in message <7km0hf$qne4@interserv.etn.com>...
> >For both sequences and associative containers, a.clear() has the
> >semantics of erase(a.begin(),a.end()), which is undefined for an empty
> >container since erase(q1,q2) requires that q1 be dereferenceable
> >(23.1.1,3 and 23.1.2,7).  When the container is empty, a.begin() is not
> >dereferenceable.
>
> True enough, but it's also not executed since a.begin() == a.end().
> Looks okay to me.

Does the standard say or imply that the iterator only needs to be
dereferenceable if it will be dereferenced?  It seems to me to simply be a
matter of saying erase(q1,q2) is only guaranteed to work if q1 is
dereferenceable.  I cannot find anything stating that it makes any
difference whether the implementation ever tries to dereference q1 or not.

Of course, I'm not worried about watching my hard drive format itself the
next time I try to clear an empty container.  I just don't like the idea
that I could write an C++ library that would do so and be able to say that
it complies with the standard.

-- Note to mods: My apologies for failing to send the DR in plain text.  It
was an accident, and I'm not sure what went wrong.  As far as I'm concerned,
you can feel free to reject any such submission.  I, for one, would be happy
to resubmit it correctly and save the embarrassment.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1999/06/26
Raw View
"P.J. Plauger" <pjp@plauger.com> writes:

>Ed Brey wrote in message <7km0hf$qne4@interserv.etn.com>...
>>For both sequences and associative containers, a.clear() has the =
>>semantics of erase(a.begin(),a.end()), which is undefined for an empty =
>>container since erase(q1,q2) requires that q1 be dereferenceable =
>>(23.1.1,3 and 23.1.2,7).  When the container is empty, a.begin() is not =
>>dereferenceable.
>
>True enough, but it's also not executed since a.begin() == a.end().
>Looks okay to me.

What do you mean by "looks okay to me"?
The behaviour is undefined, because the first argument of erase()
is not dereferencable.  It doesn't matter that the argument is
not actually dereferenced -- the parts of the standard that Ed Brey
cited say that for erase(q1, q2) the argument q1 must be dereferencable,
regardless of whether q1 == q2 or not.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3        |     -- the last words of T. S. Garp.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]