Thread Links Date Links
Thread Prev Thread Next Thread Index Date Prev Date Next Date Index

Re: Use of SNaN



On 2012-01-10 12:23:21 +0000, N.M. Maclaren wrote:
> On Jan 10 2012, Vincent Lefevre wrote:
> >>
> >>>>Sorry, I should have been more accurate.  I meant that it can be
> >>>>possible in languages (at least in C), partly based on the fact
> >>>>that IEEE 754 specifies the sNaN encoding.  In C, this can be
> >>>>done by storing a sequence of bytes using a union. Of course,
> >>>>this can only be implementation-defined because IEEE 754 specifies
> >>>>the encoding only as a bit-string (not as a sequence of bytes).
> >>
> >>Not even that.  That trick is undefined behaviour, and won't always
> >>work.
> >
> >This trick has a well-defined behavior as long as the object is
> >supported by the implementation. Now, an implementation is free
> >to regard sNaN objects as undefined behaviour. But in such a case,
> >I'm not sure that it could claim conformance to IEEE 754 (while
> >we are in the context of IEEE 754). With GCC, you can use the
> >-fsignaling-nans (experimental) option to support signaling NaNs.
> 
> I am sorry, but that is wrong, according to several vendor
> statements made to WG14, the majority view on the WG14 reflector,
> and my experience.  I was involved with WG14 at the time, with a
> particular interest in this aspect, and was supporting a wide range
> of compilers for HPC systems.  See below :-(
> 
> The undefined behaviour has nothing to do with the representation,
> but is whether the compiler is allowed to use its knowledge of
> what was last stored in a union to produce code that will break
> that trick.

Your interpretation is wrong. See the example given by the Committee
(in the "Committee Discussion"):

  http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_236.htm

The GCC developers go in the same way:

    Pay special attention to code like this:

                   union a_union {
                     int i;
                     double d;
                   };

                   int f() {
                     union a_union t;
                     t.d = 3.0;
                     return t.i;
                   }

    The practice of reading from a different union member than the one
    most recently written to (called "type-punning") is common.  Even
    with -fstrict-aliasing, type-punning is allowed, provided the
    memory is accessed through the union type.  So, the code above will
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    work as expected.

Anyway these are not mailing-lists on the C standard. So, if you
reject the case of a union, just consider the case of characters;
the C standard is clear on that point.

>  That was implementation-defined (which can include
> undefined!) in C90, I agree, but is undefined in C99 by 6.5
> paragraph 7.

In Paragraph 7, the union type is included in the list of types
allowed for accessing the object (though it should have said
union member, but I assume that this is just bad wording, see
above).

-- 
Vincent Lefèvre <vincent@xxxxxxxxxx> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)