Boost logo

Boost :

Subject: Re: [boost] [iterator] UB when implicitly using default constructed counting_iterator<unsigned>
From: Peter Sommerlad (peter.sommerlad_at_[hidden])
Date: 2012-12-04 15:19:58


Hi Jeff,
On 04.12.2012, at 18:59, Jeffrey Lee Hellrung, Jr. wrote:

> On Sun, Dec 2, 2012 at 8:41 AM, Peter Sommerlad <peter.sommerlad_at_[hidden]>wrote:
> just consider the following small program:
>>
>> #include <iostream>
>> #include <boost/iterator/counting_iterator.hpp>
>>
>> int main(){
>> std::cout << unsigned() << '\n'; // zero
>> std::cout << *boost::counting_iterator<unsigned>()<< '\n';//
>> undefined behavior
>> }
>>
>
> Not quite UB :) It just outputs an undefined value. It won't blow up the
> moon, for example.

That is not true. According to the standard reading an uninitialized value incurs undefined behavior. While in practice your computer might not explode, it is inherently unsafe and unportable to rely on something like this. See below. Therefore my concerns (I am a regular attendant of the standard committee meetings, so I can check with the real experts about that, if you doubt).

4.1 Lvalue-to-rvalue conversion [conv.lval]

        • 1 A glvalue (3.10) of a non-function, non-array type T can be converted to a prvalue.53 If T is an incomplete type, a program that necessitates this conversion is ill-formed. If the object to which the glvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior. If T is a non-class type, the type of the prvalue is the cv-unqualified version of T. Otherwise, the type of the prvalue is T.54

>
> I understand your concerns, I think, but I believe it's somewhat misguided.
> I believe your proposal could do at least as much to mask errors as it will
> to find errors. Indeed, your original example would've silently worked as
> expected (with the present implementation of filter_iterator, anyway) with
> your proposed change, even though it's (still) incorrect usage.

I still believe it is much better for a library to not incur silently undefined behavior, but to provide a defined default value, even if it is unusable in general, but detectable.

if I would have used 0 as the start iterator in the original example instead of 1 I would have seen something is wrong with my unit tests. However, the undefined behavior didn't help me detecting it.

Regards
Peter.

-- 
Prof. Peter Sommerlad
Institut für Software: Bessere Software - Einfach, Schneller!
HSR Hochschule für Technik Rapperswil
Oberseestr 10, Postfach 1475, CH-8640 Rapperswil
http://ifs.hsr.ch http://cute-test.com http://linticator.com http://includator.com
tel:+41 55 222 49 84 == mobile:+41 79 432 23 32
fax:+41 55 222 46 29 == mailto:peter.sommerlad_at_[hidden]

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk