Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > What is the defined behavior of past bound iterator

Reply
Thread Tools

What is the defined behavior of past bound iterator

 
 
PengYu.UT@gmail.com
Guest
Posts: n/a
 
      04-06-2006
I'm wondering is the standard defined behavior of past bound iterator.

In the following example it seems that afer first "--it", it point to
-1 index. I'm wondering if it is true independent of which STL
implementation that I am using.


#include <iostream>
#include <vector>

int main(int argc, char *argv[]) {
std::vector<int> v;
for(int i = 0; i < 10; ++ i) {
v.push_back(i);
}
std::vector<int>::iterator it = v.begin();
-- it;
-- it;
std::cout << *it << std::endl;
++ it;
std::cout << *it << std::endl;
++ it;
std::cout << *it << std::endl;
++ it;
std::cout << *it << std::endl;
}

The output:
0
0
0
1

 
Reply With Quote
 
 
 
 
Noah Roberts
Guest
Posts: n/a
 
      04-06-2006

wrote:
> I'm wondering is the standard defined behavior of past bound iterator.


The defined behavior is that the behavior is undefined.

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      04-06-2006
wrote:
> I'm wondering is the standard defined behavior of past bound iterator.


Where did you find that term "past bound"?

> In the following example it seems that afer first "--it", it point to
> -1 index. I'm wondering if it is true independent of which STL
> implementation that I am using.


Yes, it's true independent of whatever. Its behavour is _undefined_.

> #include <iostream>
> #include <vector>
>
> int main(int argc, char *argv[]) {
> std::vector<int> v;
> for(int i = 0; i < 10; ++ i) {
> v.push_back(i);
> }
> std::vector<int>::iterator it = v.begin();
> -- it;


Bam!!! 'it' is now _invalid_.

> -- it;


BANG!!! Undefined behaviour. Everything after that is irrelevant.

> std::cout << *it << std::endl;
> ++ it;
> std::cout << *it << std::endl;
> ++ it;
> std::cout << *it << std::endl;
> ++ it;
> std::cout << *it << std::endl;
> }
>
> The output:
> 0
> 0
> 0
> 1


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Pete C
Guest
Posts: n/a
 
      04-06-2006
Victor Bazarov wrote:
> > std::vector<int>::iterator it = v.begin();
> > -- it;

>
> Bam!!! 'it' is now _invalid_.


Do you not get undefined behaviour at this point? Are you saying that
if we did "exit(0);" now, the program would be OK? I didn't realise
that.

>
> > -- it;

>
> BANG!!! Undefined behaviour. Everything after that is irrelevant.
>


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      04-06-2006
Pete C wrote:
> Victor Bazarov wrote:
>>> std::vector<int>::iterator it = v.begin();
>>> -- it;

>>
>> Bam!!! 'it' is now _invalid_.

>
> Do you not get undefined behaviour at this point? Are you saying that
> if we did "exit(0);" now, the program would be OK? I didn't realise
> that.


Invalidation of an iterator is a normal thing. Undefined behaviour
occurs when you try to _use_ an invalid iterator.

>>
>>> -- it;

>>
>> BANG!!! Undefined behaviour. Everything after that is irrelevant.


Here, decrementing means using. You need to know its value to give
it a new one. But evaluating the iterator when it's invalid is not
defined.

V
--
Please remove capital As from my address when replying by mail


 
Reply With Quote
 
Pete C
Guest
Posts: n/a
 
      04-07-2006
Victor Bazarov wrote:
> Pete C wrote:
> > Victor Bazarov wrote:
> >>> std::vector<int>::iterator it = v.begin();
> >>> -- it;
> >>
> >> Bam!!! 'it' is now _invalid_.

> >
> > Do you not get undefined behaviour at this point? Are you saying that
> > if we did "exit(0);" now, the program would be OK? I didn't realise
> > that.

>
> Invalidation of an iterator is a normal thing. Undefined behaviour
> occurs when you try to _use_ an invalid iterator.


OK, I just had a rummage around in the standard. In 24.1.4 (Table 75)
it say that a precondition for --r (where r is a bidirectional
iterator) is that there must exist an iterator s such that r == ++s.
But because ++s is only valid for iterators that are dereferencable
(Table 74), this condition cannot be satisfied when r lies at the
beginning of a sequence.
So seems to me that a statement like --v.begin(); is a violation of
this precondition. If not, could you please explain where I have gone
wrong? Thanks...

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      04-07-2006
Pete C wrote:
> [..]
> OK, I just had a rummage around in the standard. In 24.1.4 (Table 75)
> it say that a precondition for --r (where r is a bidirectional
> iterator) is that there must exist an iterator s such that r == ++s.
> But because ++s is only valid for iterators that are dereferencable
> (Table 74), this condition cannot be satisfied when r lies at the
> beginning of a sequence.
> So seems to me that a statement like --v.begin(); is a violation of
> this precondition. If not, could you please explain where I have gone
> wrong? Thanks...


I think you got it right. Note that --v.end() is not a violation (to
be honest, I've never seen "--v.begin()" anywhere, but the 'end' one I
have, indeed).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Michiel.Salters@tomtom.com
Guest
Posts: n/a
 
      04-10-2006

Victor Bazarov wrote:
> Pete C wrote:
> > Victor Bazarov wrote:
> >>> std::vector<int>::iterator it = v.begin();
> >>> -- it;
> >>
> >> Bam!!! 'it' is now _invalid_.

> >
> > Do you not get undefined behaviour at this point? Are you saying that
> > if we did "exit(0);" now, the program would be OK? I didn't realise
> > that.

>
> Invalidation of an iterator is a normal thing. Undefined behaviour
> occurs when you try to _use_ an invalid iterator.
>
> >>
> >>> -- it;
> >>
> >> BANG!!! Undefined behaviour. Everything after that is irrelevant.

>
> Here, decrementing means using. You need to know its value to give
> it a new one. But evaluating the iterator when it's invalid is not
> defined.


Nope, it isn't. This is intentional; it allows for e.g. simple linked
list
implementations. The first iterator will have list::iterator:rev==0,
and --it; translates to it = *(it.prev);.

Else, you should be able to decrement it N times, increment it N times,
and get back to begin. Logically, that means the iterator would have to
store N (which is a large overhead for single-linked lists)
Furthermore,
it would be very tricky to keep such an N-before-begin iterator valid
if
one inserts an element at the begin of such a list.

Lots of pain, little gain: a good reason to disallow the creation of
such
invalid iterators altogether. After all, it's equally invalid for
arrays, and we
could handle those as well.

HTH,
Michiel Salters

HTH,
Michiel Salters.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Lower bound & Upper bound sunil panda Java 9 10-07-2008 08:32 PM
How to represent the data in a not bound control via bound control Mario Krsnic ASP .Net 0 06-23-2006 07:38 AM
Forward iterators and past-the-end iterator Mark Stijnman C++ 5 01-28-2006 08:56 PM
#if (defined(__STDC__) && !defined(NO_PROTOTYPE)) || defined(__cplusplus) Oodini C Programming 1 09-27-2005 07:58 PM
Getting lower-bound and upper-bound of strings input Rhiner Dan C++ 1 03-27-2005 02:03 AM



Advertisments