Topic: Decrementing begin() / Incrementing end()


Author: James Kuyper <kuyper@wizard.net>
Date: 2000/02/04
Raw View
scleary@jerviswebb.com wrote:
>
> > What does the standard have to say about decrementing an iterator that is
> > pointing to the beginning of a container and/or incrementing an iterator
> > pointing at the end of a container?
>
> It's undefined.  You can only increment a dereferenceable iterator, and your
> results are either a dereferenceable iterator or a past-the-end iterator
> [24.1.3/1, requirement for '++r']. ...

But it doesn't say that a past-the-end iterator is not dereferenceable.

> ...  Similarly, decrementing a begin()
> iterator is undefined [24.1.4/1, requirement for '--r'], because it requires
> that "there exists s such that r == ++s".

And how do you know that there is no such 's' for begin()?

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/02/04
Raw View
John Potter wrote:
>
> On 2 Feb 2000 17:52:22 GMT, James Kuyper <kuyper@wizard.net> wrote:
>
> :
> : John Potter wrote:
> : >
> : > On Tue, 1 Feb 2000 02:27:08 CST, James Kuyper <kuyper@wizard.net> wrote:
> : > Would the fact that an end() iterator is not dereferencable and that
> :
> : Citation please?
> :
> : 24.1 p5 says that "The library never assumes that past-the-end values
> : are dereferenceable."
>
> Therefor, I assumes that they are not dereferenceable.

But I'm a user, not a library implementor; that statement doesn't
constrain me, only the library. That statement means that I can create a
container class whose past-the-end values are not de-referenceable, and
safely use that container with the standard library. It doesn't say that
the standard-defined containers have the same privelege. I believe that
they do, I just can't figure out where the standard says so.

---
[ 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: kanze@gabi-soft.de
Date: 2000/01/31
Raw View
James Kuyper <kuyper@wizard.net> writes:

|>  kanze@gabi-soft.de wrote:

|>  > James Kuyper <kuyper@wizard.net> writes:

|>  > |>  Paul Carter <paul.carter@house-of-vision.co.uk> wrote:
|>  >
|>  > |>  > What does the standard have to say about decrementing an iterator
|>  > |>  > that is pointing to the beginning of a container and/or
|>  > |>  > incrementing an iterator pointing at the end of a container?
|>  ....
|>  > I would hope that on most implementations, they would either throw an
|>  > exception, or abort the process.  Since the actual behavior is
|>  > undefined, the implementation is free to define it, and these seem to be
|>  > the most useful definitions.

|>  But such a definition always carries a cost; one which needn't be
|>  incurred if the container is used properly. I'd like any such behavior
|>  to be an option that can be turned off if efficiency is a concern.

Most error checking carries a cost.  In the end, the question is simply:
do you want a program that is correct, or do you prefer one that is
fast?

And I know that that is an enormous simplification.  Nevertheless, an
implementation that doesn't check as its *default* behavior can only be
considered irresponsible.

|>  > |>  It's mostly implicitly undefined behavior. About the only
|>  > |>  thing I could find that was relevant was Section 24.1 p6,
|>  > |>  which says: "An iterator j is called _reachable_ from an
|>  > |>  iterator i if and only if there is a finite sequence of
|>  > |>  applications of ++i that makes i == j. If j is reachable from
|>  > |>  i, they refer to the same container."

|>  > Of course, the standard "supposes" that the ++i are defined.  If you
|>  > invoke undefined behavior, by incrementing beyond the end of the
|>  > container, for example, nothing the standard says holds anymore.

|>  Undefined behavior means that the standard "imposes no requirements".
|>  It's definitions don't cease to apply, only the requirements that are
|>  based upon them. What constitutes a reachable iterator remains defined.

Undefined behavior means that the standard imposes no requirements on
the implementation when given a program which contains it.  In the face
of undefined behavior, all other clauses of the contract (the standard)
are null and void.

Incrementing an iterator beyond the end of a container is undefined
behavior.  Thus, nothing which might appear in section 24.1 (or anywhere
else, for that matter) is relevant.

|>  > |>  I think this clause goes too far; it seems to require that ++
|>  > |>  be range-checked for all iterators, including ordinary
|>  > |>  pointers. Either that, or iterators that are or contain
|>  > |>  pointers must all be considered to point to a single container
|>  > |>  that contains all other objects that use the same memory pool.

|>  > No.  Other text requires that the programmer ensure that ++ never goes
|>  > beyond the end.

|>  The standard defines "reachable" in terms of a hypothetical sequence of
|>  operations.

Maybe I'm just dense, but I would suppose that this "hypothetical
sequence of operations" must be legal.  Incrementing beyond the end of a
container isn't -- a legal program thus cannot contain this hypothetical
sequence of operations.

|>  It doesn't require that the code actually perform those
|>  operations.

No.  It only requires that it *could* perform them, with the results
indicated.  In order to perform them, the code must be legal, and not
invoke undefined behavior.

|>  Based upon that hypothetical sequence of operations, two
|>  iterators for which it would work are in the same container, even if the
|>  code never actually performs that sequence, even if that sequence would
|>  allow undefined behavior if it were in fact performed. This either
|>  extends the concept of a container farther than may have been intended,
|>  or requires range-checked pointers to interrupt that sequence.

Or requires that the standard restrict the legality of the operations
involved elsewhere.  Which it does.

--
James Kanze                         mailto:James.Kanze@gabi-soft.de
Conseils en informatique orientie objet/
                  Beratung in Objekt orientierter Datenverarbeitung
Ziegelh|ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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: Hyman Rosen <hymie@prolifics.com>
Date: 2000/01/31
Raw View
James Kuyper <kuyper@wizard.net> writes:
> That's not what the standard says. A definition isn't a requirement.
> Only the requirements are waived for code with undefined behavior, not
> any other part of the standard. Without the requirements that they're
> used by, the definitions are nearly useless, but they're still somewhat
> useful for describing the nature of the undefined behavior that does
> occur.

Absolutely incorrect. If a program execution encounters undefined
behavior, the Standard places no requirements on the behavior of
that execution at all, before, after, or during the actual undefined
behavior. Talking about the "nature of the undefined behavior" is
meaningless with respect to the Standard, although one can investigate
the behavior of a particular implementation. Even then, unless the
implementor gives you specific documentation, it would be foolish to
rely upon observed behavior, because you have no idea whether this
behavior would be reproduced in all circumstances by the current
implementation, or at all by future upgrades.


[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/02/01
Raw View
kanze@gabi-soft.de wrote:
>
> James Kuyper <kuyper@wizard.net> writes:
....
> Undefined behavior means that the standard imposes no requirements on
> the implementation when given a program which contains it. ...

Correct.

> ... In the face
> of undefined behavior, all other clauses of the contract (the standard)
> are null and void.

That's not what the standard says. A definition isn't a requirement.
Only the requirements are waived for code with undefined behavior, not
any other part of the standard. Without the requirements that they're
used by, the definitions are nearly useless, but they're still somewhat
useful for describing the nature of the undefined behavior that does
occur.

> Incrementing an iterator beyond the end of a container is undefined
> behavior.  Thus, nothing which might appear in section 24.1 (or anywhere
> else, for that matter) is relevant.

For iterators which happen to be pointers to objects, it's perfectly
clear that you can't safely iterate out of the object. However, I
couldn't find comparable wording for containers, as opposed to objects.
Have you found a statement to the contrary? That's what the original
poster was asking about. If it's undefined behavior, it's only
implicitly undefined.

In any event, we're not talking about code that iterates beyond the end
of the container. We're talking about an iterator which would, as part
of the undefined behavior that would happen if it were iterated far
enough, compare equal to a different iterator. This can happen even in
perfectly legal code, for which every aspect of the standard applies. If
so, then the second iterator is reachable from the first. I admit that I
can't figure out any significant consequence of that fact that would
matter.

....
> |>  The standard defines "reachable" in terms of a hypothetical sequence of
> |>  operations.
>
> Maybe I'm just dense, but I would suppose that this "hypothetical
> sequence of operations" must be legal. ...


That's not specified. This isn't a requirement that only applies if a
given piece of code is executed; it's a definition that applies only if
a hypothetical sequence of operations were executed, apparently without
regard to whether or not that sequence is actually executed.

....
> |>  It doesn't require that the code actually perform those
> |>  operations.
>
> No.  It only requires that it *could* perform them, with the results
> indicated. ...

Correct.

> ... In order to perform them, the code must be legal, and not
> invoke undefined behavior.

Illegal code can still perform those operations, with the undefined
behavior taking the form that the indicated results were achieved. If
the undefined behavior would in fact produce the indicated results, then
the second iterator is reachable from the first.

I can't think of any meaningful consequence to this definition, I just
think it's too broad. I don't have a suggested alternative wording.

---
[ 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: Hyman Rosen <hymie@prolifics.com>
Date: 2000/02/01
Raw View
kanze@gabi-soft.de writes:
> And I know that that is an enormous simplification.  Nevertheless, an
> implementation that doesn't check as its *default* behavior can only be
> considered irresponsible.

Hence the design of Ada, as opposed to C or C++. In C++ the default for
most behavior is unsafe, and that carries through into most implementations
of STL, although some have the ability to enable checking.

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/02/01
Raw View

Hyman Rosen wrote:
>
> James Kuyper <kuyper@wizard.net> writes:
> > That's not what the standard says. A definition isn't a requirement.
> > Only the requirements are waived for code with undefined behavior, not
> > any other part of the standard. Without the requirements that they're
> > used by, the definitions are nearly useless, but they're still somewhat
> > useful for describing the nature of the undefined behavior that does
> > occur.
>
> Absolutely incorrect. If a program execution encounters undefined
> behavior, the Standard places no requirements on the behavior of
> that execution at all, before, after, or during the actual undefined
> behavior. Talking about the "nature of the undefined behavior" is
> meaningless with respect to the Standard, ...

Which of course does not mean that it's meaningless.

> ...although one can investigate
> the behavior of a particular implementation. Even then, unless the
> implementor gives you specific documentation, ...

It's quite ordinary for some kinds of behavior that's undefined by the
standard, to be defined by the implementation. When the implementation
does choose to define such behavior, it needs words to convey those
definitions, and many of the most useful words that are relevant are
technical terms defined by the Standard.

If you want to claim that "imposes no requirements" somehow also
includes undoing the definitions of terms provided by the standard, what
does that mean? Does that mean that an implementation which chooses to
provide a definition for behavior which the standard leaves undefined,
must redundantly provide replacement definitions for the any technical
terms it uses in that description? After all, you're claiming that the
definitions provided by the standard have somehow been "lost".
Personally, I think they should only have to define terms that have
meanings different from the meanings of the terms defined by the
standard.

---
[ 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: Hyman Rosen <hymie@prolifics.com>
Date: 2000/02/01
Raw View
James Kuyper <kuyper@wizard.net> writes:
> If you want to claim that "imposes no requirements" somehow also
> includes undoing the definitions of terms provided by the standard, what
> does that mean? Does that mean that an implementation which chooses to
> provide a definition for behavior which the standard leaves undefined,
> must redundantly provide replacement definitions for the any technical
> terms it uses in that description? After all, you're claiming that the
> definitions provided by the standard have somehow been "lost".
> Personally, I think they should only have to define terms that have
> meanings different from the meanings of the terms defined by the
> standard.

Well, that's up to them, isn't it? The Standard imposes no requirements,
so the implementor can say that the terms defined by the Standard still
hold after certain undefined behaviors that the implementor chooses to
define. In the absence of such documentation, the definitions of the
Standard are irrelevant, since the Standard says nothing about the
behavior of the program.

If an implementation chose to tersely state that a particular undefined
action was defined and gave its behavior, I would assume that the normal
definitions of the Standard held. Is that what you're after?


[ 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: jpotter@falcon.lhup.edu (John Potter)
Date: 2000/02/01
Raw View
On Tue, 1 Feb 2000 02:27:08 CST, James Kuyper <kuyper@wizard.net> wrote:

: For iterators which happen to be pointers to objects, it's perfectly
: clear that you can't safely iterate out of the object. However, I
: couldn't find comparable wording for containers, as opposed to objects.
: Have you found a statement to the contrary? That's what the original
: poster was asking about. If it's undefined behavior, it's only
: implicitly undefined.

Would the fact that an end() iterator is not dereferencable and that
being dereferencable is a precondition for operator++ in the tables
be sufficient?  The tables also have a precondition for operator--
that there must be an iterator such that ++it yields the original.

John


[ 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: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 2000/02/01
Raw View
Hyman Rosen <hymie@prolifics.com> wrote in message
news:t7puuiosnf.fsf@calumny.jyacc.com...
> kanze@gabi-soft.de writes:
> > And I know that that is an enormous simplification.  Nevertheless, an
> > implementation that doesn't check as its *default* behavior can only be
> > considered irresponsible.
>
> Hence the design of Ada, as opposed to C or C++. In C++ the default for
> most behavior is unsafe, and that carries through into most
implementations
> of STL, although some have the ability to enable checking.

I think the reasoning behind the "irresponsible" design of STL is that you
can make a safe library out of an efficient one, but not the other way
around.


Andrei



[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/02/02
Raw View
Hyman Rosen wrote:
....
> If an implementation chose to tersely state that a particular undefined
> action was defined and gave its behavior, I would assume that the normal
> definitions of the Standard held. Is that what you're after?

That's basically what I was saying. Whether one iterator is reachable
from another is a matter of definitions, which don't disappear just
because the code involved has undefined behavior.

Of course, my main point was that the definition of a "reachable
iterator" still applies to iterators in code that has no undefined
behavior, regardless of whether or not the sequence whereby the first
reaches the second is one that would allow undefined behavior.


[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/02/02
Raw View
John Potter wrote:
>
> On Tue, 1 Feb 2000 02:27:08 CST, James Kuyper <kuyper@wizard.net> wrote:
>
> : For iterators which happen to be pointers to objects, it's perfectly
> : clear that you can't safely iterate out of the object. However, I
> : couldn't find comparable wording for containers, as opposed to objects.
> : Have you found a statement to the contrary? That's what the original
> : poster was asking about. If it's undefined behavior, it's only
> : implicitly undefined.
>
> Would the fact that an end() iterator is not dereferencable and that

Citation please?

23.1 p7 says that end() returns the past-the-end value for the
container.
24.1 p5 says that "The library never assumes that past-the-end values
are dereferenceable." However, there's no statement that past-the-end
values are not dereferenceable. I believe that it's a bad idea to try to
dereference them, I just can't find the relevant statement in the
standard.

In fact, there's a circularity in the standard:
A dereferenceable iterator is defined by 24.1 p5 as one for which *i is
defined. However, the iterator requirements in Tables 72 and 74 give "a
is dereferenceable" as a pre-requisite for "*a" to be defined.

Those same tables also say that ++r has a post-condition that r is
dereferenceable or past-the-end; but they don't say that those are
mutually exclusive options.


[ 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: jpotter@falcon.lhup.edu (John Potter)
Date: 2000/02/03
Raw View
On 2 Feb 2000 17:52:22 GMT, James Kuyper <kuyper@wizard.net> wrote:

:
: John Potter wrote:
: >
: > On Tue, 1 Feb 2000 02:27:08 CST, James Kuyper <kuyper@wizard.net> wrote:
: > Would the fact that an end() iterator is not dereferencable and that
:
: Citation please?
:
: 24.1 p5 says that "The library never assumes that past-the-end values
: are dereferenceable."

Therefor, I assumes that they are not dereferenceable.

: However, there's no statement that past-the-end
: values are not dereferenceable. I believe that it's a bad idea to try to
: dereference them, I just can't find the relevant statement in the
: standard.

You're right.

John


[ 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: "Paul Carter" <paul.carter@house-of-vision.co.uk>
Date: 2000/01/27
Raw View
What does the standard have to say about decrementing an iterator that is
pointing to the beginning of a container and/or incrementing an iterator
pointing at the end of a container?

I've done a few tests, on just one implementation, and found that std::list,
set and map  wrap round, whilst std::vector and deque don't.

Is this standard conforming or is the standard behaviour 'undefined'?  Does
the standard specify that they should(n't) throw out_of_bounds?

I'm asking as I'm implementing a few standard-conforming containers for a
specific application and would like to know what I can get away with in
these situations. In other words, I'm hoping the standard behaviour is
'undefined'!

thanks

--
Paul Carter
Takeley


---
[ 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: herwin@gmu.edu (Harry Erwin)
Date: 2000/01/27
Raw View
Paul Carter <paul.carter@house-of-vision.co.uk> wrote:

> What does the standard have to say about decrementing an iterator that is
> pointing to the beginning of a container and/or incrementing an iterator
> pointing at the end of a container?
>
> I've done a few tests, on just one implementation, and found that std::list,
> set and map  wrap round, whilst std::vector and deque don't.

Implementation details. I built a Btree-based set and found it very
convenient to wrap around. vector and deque won't because they are fancy
arrays.

--
Harry Erwin, PhD, <herwin@gmu.edu>,  Senior SW Analyst and
Adjunct Professor of Computer Science, George Mason University.

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/01/28
Raw View
Paul Carter <paul.carter@house-of-vision.co.uk> wrote:

> What does the standard have to say about decrementing an iterator that is
> pointing to the beginning of a container and/or incrementing an iterator
> pointing at the end of a container?
>
> I've done a few tests, on just one implementation, and found that std::list,
> set and map  wrap round, whilst std::vector and deque don't.

It's mostly implicitly undefined behavior. About the only thing I could
find that was relevant was Section 24.1 p6, which says: "An iterator j
is called _reachable_ from an iterator i if and only if there is a
finite sequence of applications of ++i that makes i == j. If j is
reachable from i, they refer to the same container."

I think this clause goes too far; it seems to require that ++ be
range-checked for all iterators, including ordinary pointers. Either
that, or iterators that are or contain pointers must all be considered
to point to a single container that contains all other objects that use
the same memory pool.

---
[ 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: kanze@gabi-soft.de
Date: 2000/01/28
Raw View
James Kuyper <kuyper@wizard.net> writes:

|>  Paul Carter <paul.carter@house-of-vision.co.uk> wrote:

|>  > What does the standard have to say about decrementing an iterator
|>  > that is pointing to the beginning of a container and/or
|>  > incrementing an iterator pointing at the end of a container?

That you shouldn't do it -- it is undefined behavior.

|>  > I've done a few tests, on just one implementation, and found that
|>  > std::list, set and map wrap round, whilst std::vector and deque
|>  > don't.

On one particular implementation.

I would hope that on most implementations, they would either throw an
exception, or abort the process.  Since the actual behavior is
undefined, the implementation is free to define it, and these seem to be
the most useful definitions.

|>  It's mostly implicitly undefined behavior. About the only thing I could
|>  find that was relevant was Section 24.1 p6, which says: "An iterator j
|>  is called _reachable_ from an iterator i if and only if there is a
|>  finite sequence of applications of ++i that makes i == j. If j is
|>  reachable from i, they refer to the same container."

Of course, the standard "supposes" that the ++i are defined.  If you
invoke undefined behavior, by incrementing beyond the end of the
container, for example, nothing the standard says holds anymore.

|>  I think this clause goes too far; it seems to require that ++ be
|>  range-checked for all iterators, including ordinary pointers. Either
|>  that, or iterators that are or contain pointers must all be considered
|>  to point to a single container that contains all other objects that use
|>  the same memory pool.

No.  Other text requires that the programmer ensure that ++ never goes
beyond the end.

--
James Kanze                         mailto:James.Kanze@gabi-soft.de
Conseils en informatique orientie objet/
                  Beratung in Objekt orientierter Datenverarbeitung
Ziegelh|ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/01/28
Raw View
kanze@gabi-soft.de wrote:
>
> James Kuyper <kuyper@wizard.net> writes:
>
> |>  Paul Carter <paul.carter@house-of-vision.co.uk> wrote:
>
> |>  > What does the standard have to say about decrementing an iterator
> |>  > that is pointing to the beginning of a container and/or
> |>  > incrementing an iterator pointing at the end of a container?
....
> I would hope that on most implementations, they would either throw an
> exception, or abort the process.  Since the actual behavior is
> undefined, the implementation is free to define it, and these seem to be
> the most useful definitions.

But such a definition always carries a cost; one which needn't be
incurred if the container is used properly. I'd like any such behavior
to be an option that can be turned off if efficiency is a concern.

> |>  It's mostly implicitly undefined behavior. About the only thing I could
> |>  find that was relevant was Section 24.1 p6, which says: "An iterator j
> |>  is called _reachable_ from an iterator i if and only if there is a
> |>  finite sequence of applications of ++i that makes i == j. If j is
> |>  reachable from i, they refer to the same container."
>
> Of course, the standard "supposes" that the ++i are defined.  If you
> invoke undefined behavior, by incrementing beyond the end of the
> container, for example, nothing the standard says holds anymore.

Undefined behavior means that the standard "imposes no requirements".
It's definitions don't cease to apply, only the requirements that are
based upon them. What constitutes a reachable iterator remains defined.

> |>  I think this clause goes too far; it seems to require that ++ be
> |>  range-checked for all iterators, including ordinary pointers. Either
> |>  that, or iterators that are or contain pointers must all be considered
> |>  to point to a single container that contains all other objects that use
> |>  the same memory pool.
>
> No.  Other text requires that the programmer ensure that ++ never goes
> beyond the end.

The standard defines "reachable" in terms of a hypothetical sequence of
operations. It doesn't require that the code actually perform those
operations. Based upon that hypothetical sequence of operations, two
iterators for which it would work are in the same container, even if the
code never actually performs that sequence, even if that sequence would
allow undefined behavior if it were in fact performed. This either
extends the concept of a container farther than may have been intended,
or requires range-checked pointers to interrupt that sequence.


[ 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              ]