Subject: Re: gcc optimizer bug in netbsd-1-6 on alpha (gcc 2.95.3 20010315 (release) (NetBSD nb3))
To: None <tech-toolchain@NetBSD.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-toolchain
Date: 08/16/2003 02:40:07
>>> [...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.
> To put it another way, the code I wrote is precisely as
> implementation dependent as the original code was with an older
> compiler.

Well, I'm not sure I agree with "precisely", but I think we are
basically in agreement on this point.

> 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.

I don't think so; I don't think the standard promises that there even
_are_ memory locations in that sense.

> ``A pointer to a union object, suitably converted, points to each of
> its members, ... and vice versa.''  X3.159-1989 3.5.2.1.

Yes, but that "suitably converted" can hide unlimited amounts of
implementation-specific magic.  In
	union { int32_t i; struct in_addr a; }
there is nothing that guarantees that i and a share any storage at all,
as far as I can see.  For example, i could be in a register and a could
be in memory.  (And if a's address is taken but i's isn't, this would
not even be unreasonable.)

> In other words, a union may be used for type punning in a standard
> conformant manner.

Not as I have understood "standard conformant"; as I understand the
term, the code is not standard conformant the moment it stores into one
member of a union and reads from another, regardless of why it is doing
that, and the implementation is free to do anything in its power, from
"working" to dumping core to, even, invoking the nasal demons (if
suitably equipped).

> Type punning itself is automatically implementation dependent.

Yes.  And the union is a clumsy but generally workable substitute for
the pointer cast...and I don't think it helps the aliasing situation
one bit, since struct in_addr cannot alias int32_t (if it could, you
could just use the cast).  Thus, the compiler is permitted to assume
that storing to the int32_t does not change the struct in_addr.
Whether today's gcc acts on that assumption I can't say, but there's no
guarantee that tomorrow's won't.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       mouse@rodents.montreal.qc.ca
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B