Subject: Re: gcc optimizer bug in netbsd-1-6 on alpha (gcc 2.95.3 20010315 (release) (NetBSD nb3))
To: der Mouse <mouse@Rodents.Montreal.QC.CA>
From: Ian Lance Taylor <ian@airs.com>
List: tech-toolchain
Date: 08/15/2003 23:17:33
der Mouse <mouse@Rodents.Montreal.QC.CA> writes:

> >>> [...] it is, of course, possible to write the earlier example in a
> >>> standard conforming fashion.
> >> How?  I can't see any way short of allocating a struct in_addr and
> >> copying.
> > I'm not going to pretend that it is pretty, but this should work for
> > all C compilers:
> > [...code that assumes you can store into one member of a union and
> > fetch from a different one...]
> 
> I don't think such code is standard-conforming.  I haven't read the
> standard, but everyone who has and from whom I've heard on the subject
> has said this; K&Rv2 agrees, stating that "the results are
> implementation-dependent if something is stored as one type and
> extracted as another", in the main body of the book, and "[i]n general,
> a member of a union may not be inspected unless the value of the union
> has been assigned using that same member" (there is an exception for
> struct elements that share an initial sequence of members), in the
> reference material in Appendix A.

The results are implementation dependent in the sense that the
standard doesn't make any promises about how types are represented in
memory.  That was always true.  To put it another way, the code I
wrote is precisely as implementation dependent as the original code
was with an older compiler.

The code I wrote is standard conformant in the sense that the standard
promises that all objects in a union are stored in the same memory
location.  ``A pointer to a union object, suitably converted, points
to each of its members, ... and vice versa.''  X3.159-1989 3.5.2.1.

In other words, a union may be used for type punning in a standard
conformant manner.  Type punning itself is automatically
implementation dependent.  The code is already presuming that an int
really can be treated as the same as a struct in_addr.  Nothing
changes there.

Ian