Topic: Defect Report: bidirectional iterator assertion typo


Author: ysapir@yahoo.com (ys)
Date: 17 Oct 02 13:04:59 GMT
Raw View
 [Moderator's note: this defect report has been
 forwarded to the C++ committee. -moderator.]

Section: 24.1.4 [lib.bidirectional.iterators]

Following a discussion on the boost list regarding end iterators and
the possibility of performing operator--() on them, it seems to me
that there is a typo in the standard.  This typo has nothing to do
with that discussion.

I have checked this newsgroup, as well as attempted a search of the
Active/Defect/Closed Issues List on the site for the words "s is
derefer" so I believe this has not been proposed before.  Furthermore,
the "Lists by Index" mentions only DR 299 on section 24.1.4, and DR
299 is not related to this issue.

Also, while I do not have the standard, I am using what Dave Abrahams
quoted to me in his reply on this topic, and therefore, I believe this
is the current standard's text.  It is so written in the Public Review
Document.

The standard makes the following assertion on bidirectional iterators,
in section 24.1.4 [lib.bidirectional.iterators], Table 75:

                         operational  assertion/note
expression  return type   semantics    pre/post-condition

--r          X&                        pre: there exists s such
                                       that r == ++s.
                                       post: s is dereferenceable.
                                       --(++r) == r.
                                       --r == --s implies r == s.
                                       &r == &--r.

(See http://aspn.activestate.com/ASPN/Mail/Message/boost/1395763)

In particular, "s is dereferenceable" seems to be in error.  It seems
that the intention was to say "r is dereferenceable".

There are several interpretations for the current reading.  Firstly,
because s is referenced in the precondition as "++s", the reader is
not sure if the intention is the s prior to operator++ (as defined by
"there exists s") or afterwards.  Secondly, there is some ambiguity
in my opinion from the fact s itself is totally unrelated to the
action of operator--.

These interpretations are:

1) s is dereferenceable before ++s is applied.  However, we know s is
dereferenceable before operator++ on s (in precondition) because that
is a precondition of operator++.  So the precondition cannot even be
"instantiated" without s being dereferenceable to begin with.
Therefore, this interpretation is rather superfluous.

2) If the intention was that --r operates only on those iterators that
are dereferenceable results of ++s, then it could have been stated as
a precondition of r: "r is dereferenceable and there exists s such
that r = ++s".  Because it does not say so, we can assume r is not
necessarily dereferenceable, and ++s which is equivalent to r, is also
not necessarily dereferenceable.

3) If the postcondition means that s is dereferenceable after the
operation, but not necessarily before, it implies the somewhat curious
notion that --end() can make end() dereferenceable.  This is clearly
not the case in any current implementation of standard containers.

Besides being ambiguous as to which interpretation is meant, the
reader is left to wonder whether it's interpretation 1 (which is
superfluous information), interpretation 2 (which has effects on
implementations since operator-- would not have to work on end
iterators), or interpretation 3 (which is probably absurd
information).

On the other hand, if it were to say "r is dereferenceable" it would
make perfect sense.  Since s must be dereferenceable prior to
operator++, then the natural result of operator-- (to undo operator++)
would be to make r dereferenceable.  Furthermore, without other
assertions, and basing only on precondition and postconditions, we
could not otherwise know this.  So it is also interesting information.

In any case, the current reading is at least ambiguous (see
interpretations 1 - 3).  For interpretation 3, the reading is in
error.  "r is dereferenceable" as either a precondition or
postcondition
would clarify the ambiguity, and make much more sense.  My proposed
correction, "r is dereferenceable" as a postcondition, in place of the
current postcondition, would make the most sensible reading.

Hence, I believe the statement in the standard is a typographical
mistake, and should state instead "postcondition: r is
dereferenceable."
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]