Opened 14 years ago

Last modified 8 years ago

#2640 new Bugs

Legal forward iterators cannot store their referents (was: counting_iterator::reference lifetime tied to iterator) — at Version 3

Reported by: schoedl Owned by: Dave Abrahams
Milestone: Boost 1.38.0 Component: iterator
Version: Boost 1.37.0 Severity: Problem
Keywords: counting_iterator reverse_iterator Cc: flast@…

Description (last modified by Dave Abrahams)

The iterators library needs a redesign based on the facts noted in this comment

The original report is below.


Currently, counting_iterator<T>::reference is Incrementable const&. This makes reverse_iterator< counting_iterator<T> >::dereference return a reference to a temporary variable:

typename super_t::reference dereference() const { return *boost::prior(this->base()); }

The problem is that iterator::reference is expected to stay valid even if the iterator it was obtained from is dead.

Change History (4)

by schoedl, 13 years ago

Attachment: counting_iterator.hpp.patch added

patch

comment:1 by Dean Michael Berris, 12 years ago

I'm not sure I understand the consequences of this patch. Iterator references are meant to be valid only while the actual source of the data is still valid. This is the same reason why iterators typically don't own the data it refers to.

I don't see why the semantics should change for counting iterator. Unless there is really a bug with the implementation (i.e., a reproducible crash or relying on undefined behavior) then I don't see why this patch solves anything.

comment:2 by Dave Abrahams, 12 years ago

The history of iterators that own the object they reference is somewhat complicated. counting_iterator does own its referent. To be a valid forward iterator, its reference type must be a true C++ reference. Otherwise, it would be limited to input iterator. Trying to accomodate forward iterators that store their referent caused innumerable contortions in the design of this library.

However, recent re-readings of the C++03 standard make it clear to me that such iterators are not allowed to be forward iterators anyway. In particular, below table 74 it says:

— If a and b are both dereferenceable, then a == b if and only if *a and *b are the same object.

So IMO, the library design needs to be revisited in terms of this new understanding. I don't want to address it piecemeal, because anything we do will break someone's code, and I want to make those changes all at once.

comment:3 by Dave Abrahams, 12 years ago

Description: modified (diff)
Summary: counting_iterator::reference lifetime tied to iteratorLegal forward iterators cannot store their referents (was: counting_iterator::reference lifetime tied to iterator)
Note: See TracTickets for help on using tickets.