Boost logo

Boost :

Subject: Re: [boost] [iterator] UB when implicitly using default constructed counting_iterator<unsigned>
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2012-12-01 12:39:56


On 12/01/2012 07:20 AM, Peter Sommerlad wrote:
> Hi Jeff
> On 01.12.2012, at 02:53, Jeffrey Lee Hellrung, Jr. wrote:
>>> And a default
>>> initialized scalar type, isn't.
>> "isn't"...what, exactly?
> it isn't initialized with a defined value.
> struct X{
> X(){}
> unsigned x;
> };
> void foo(){
> X y; // -> y.x has an uninitialized value AFAIK if it is local
> }
> that is the situation we run into with the default constructed counting_iterator<unsigned>()

IMO, this is a good thing. Any use of a default
constructed counting_iterator is probably wrong,
no matter what (arbitrary) value is chosen. As
such, it's better to leave it uninitialized, so
these errors can be caught by tools like valgrind.

>> I'm not opposed to giving defined behavior to a default constructed
>> counting_iterator< [integral type] >, I'm just not sure what that defined
>> behavior should be. Maybe I'm over-analyzing it...
> I still believe the most simple change I suggested is enough (at least it would cover my situation well enoughi).

Your use case is very error prone. It only works
because you started the iteration at 1, not 0.

> Those input iterators where a default constructed one is the end iterator is IMHO more of an exception, because it is a special case for the stream iterators.

Any other iterator gives undefined behavior when
it's default constructed. I don't see why counting_iterator
should be different.

> Your idea with std::numberic_limits< Iterator >::max() requires a much more complex solution with template meta programming, i.e., enable_if<is_arithmetic<Iterator>> or similar. And it won't provide the default value of Iterator, which is zero in the case of the built-in arithmetic types, i.e., unsigned().
> What do you think?

In Christ,
Steven Watanabe

Boost list run by bdawes at, gregod at, cpdaniel at, john at