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 <>
List: tech-toolchain
Date: 08/16/2003 16:48:23
der Mouse <mouse@Rodents.Montreal.QC.CA> writes:

> > Note that this is based only on the type of the pointer, not on the
> > actual object which the pointer holds the address of.
> And here, mostly - the conversion cannot depend on the data stored in
> the object, but it can depend on other properties of it (such as, for
> example, what kind of memory it's allocated in, on a machine with
> different kinds of memory).

I'm not sure about that.  I think that would only be true when using
some sort of extension to the standard.

The standard says (3.3.4) ``It is guaranteed...that a pointer to an
object of given alignment may be converted to a pointer to an object
of the same alignment or a less strict alignment and back again; the
result shall compare equal to the original pointer.''

To me that seems fairly clear: you can cast back and forth between
pointer types and get the same result, subject only to alignment
constraints.  Alignment is defined as ``a requirement that objects of
a particular type be located on storage boundaries with addresses that
are particular multiples of a byte address.''

Not that it matters for the case of type punning.

> > In other words, given
> >     union foo { int32_t i; struct in_addr a; } u;
> [I added the tag "foo" -dM]
> > the standard guarantees that
> >     &u.i == (int32_t *) &u.a
> That &u.i == (int32_t *)&u, and that &u.a == (struct in_addr *)&u, and
> that &u.i = (int32_t *)(union foo *)&u.a, yes, but not, as far as I can
> see, that &u.i == (int32_t *)&u.a.

OK, I see what you are getting at here.  You may well be right.  At
least, I can't think of any reason that you are wrong.

I will note something I missed earlier, that the standard says ``a
union is a type consisting of a sequence of named members, whose
storage overlap.''  Unfortunately, I don't think the notion of
overlapping storage is defined other than by pointer equality.

Looking at the gcc mailing lists, it does look like the gcc
maintainers think that type punning is not supported by the standard.
So I am probably wrong.

> > Well, more precisely, the behaviour of reading from one field of a
> > union after writing to another is ``implementation defined,'' [
> > constratsed with...] ``undefined behaviour,'' [...].
> So, the only difference is that an implementation is required to
> document - to an unspecified degree of precision - what you get.  I
> don't see this as making a significant difference to the utility of a
> coding technique in a compiler-independent sense.
> A compiler could, for example, document that storing into one member
> and reading from a different one returns some value of the type of the
> member read, but what that value is may vary arbitrarily from moment to
> moment and may or may not bear any relation to the value stored into
> the first member.  That would satisfy the documentation requirement and
> still permit allocating one member in a register and another in memory.

In theory, sure.  In practice, such a compiler would not be used, so
it doesn't seem worth worrying about.  I know that we are arguing
about theory here; what I'm trying to say is that there is a real
difference between ``implementation defined behaviour'' and
``undefined behaviour:'' the former is much more likely to conform to
traditional expectations of C.

> > For what it's worth, gcc's documentation clearly states that type
> > punning using a union is not affected by aliasing.
> Today's documentation.  This means that the union trick will work with
> gcc - today's gcc, that is.  That was never in dispute, or at least I
> never thought it was.

Yes.  But since type punning is an essential part of C, and gcc is
explicitly documenting a form of type punning which works, I think it
is quite unlikely to change.

It's interesting to note this proposal to the C standard:
although it does not appear to have any associated actions yet.