Boost logo

Boost :

Subject: Re: [boost] [contract] toward N3351 concepts
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2012-10-01 16:48:57


AMDG

On 10/01/2012 03:43 AM, Andrew Sutton wrote:
>> Unless you mean to say that any program that uses
>> a NaN in any way has undefined behavior, this notion
>> of a "well-formed value" seems arbitrary and capricious.
>
> The notion of "well-formed value" comes for Elements of Programming.
> NaN is given as an example of something that is not well-formed. It's
> defined in the first couple of pages, IIRC. Any state of an object
> that does represent a value (e.g., NaN does not represent a real
> number) is not a well-formed value. I can assure that neither Alex nor
> Paul would consider the definition to be arbitrary or capricious.
>

Well, I beg to differ.

> A program that checks for NaN as the result of an invalid computation
> does not have undefined behavior because it is explicitly checking for
> that state. A program that uses NaN as if it were a real number should
> have undefined behavior.
>

That's no different from saying that a program that uses
2 + 3i as if it were a real number has undefined behavior.
If you make an assumption about the value of an object,
then it's likely to be undefined behavior if that
assumption doesn't hold.

> It is easy to construct examples of programs where NaN breaks the
> postconditions of STL algorithms:
>
> double s[] { NaN };
> assert(find(s, s + 1, NaN) == s); // will fail
>
> double s[] { ..., NaN, ... };
> sort(s, s + N);
> assert(is_sorted(s, s + N)); // probably fails
>
> Comparisons on NaN do not conform to the usual semantics of equality
> and ordering, and so the programs have undefined behavior.

Some algorithms obviously won't work, but others like
copy that don't depend on comparison will work fine.
You can even use find or is_sorted if you pass a custom
predicate that handles NaN's in a way consistent with
what the algorithm expects. In short, the fact that
NaN's cause undefined behavior is a property of
the concept map of comparison for double, not
a property of double in itself.

> This is
> because the algorithms are generic and are only concerned with the
> comparison of values, not the checking of those computations for
> invalid results.
>
> There's nothing wrong with having a type or set of types with a
> representation that includes an ill-formed value. It can be very
> useful for checking error states. However, such states may not be
> included in the set of values represented by that type.
>

As far as I'm concerned, any value that can exist
at all is a member of the set of values represented
by the type. The fact that some values are forbidden
in certain contexts is irrelevant.

A NaN:
- Can have various basic operations applied to it
  with well-defined results.
- Can appear in program input and output.
- Can be used safely in some generic algorithms.

Therefore, I maintain that a NaN is a legitimate
value. Saying that it is ill-formed depends solely
on the intent of the programmer in specific
cases and is not a universal truth.

In Christ,
Steven Watanabe


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