Date: Tue, 4 Aug 1998 21:12:40 -0400 (EDT) From: Chuck Robey <chuckr@glue.umd.edu> To: Thomas David Rivers <rivers@dignus.com> Cc: freebsd-hackers@FreeBSD.ORG, Nicolas.Souchu@prism.uvsq.fr Subject: Re: C and static initialization with unions Message-ID: <Pine.BSF.4.00.9808042107000.409-100000@picnic.mat.net> In-Reply-To: <199808050144.VAA17156@lakes.dignus.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 4 Aug 1998, Thomas David Rivers wrote:
> >
> > On Tue, 4 Aug 1998, Thomas David Rivers wrote:
> >
> > > Also - you should be aware that ANSI forbids assigning to one element
> > > of a union and referencing a different element. (Basically, the
> > > 'type-punning' problem) C compilers are allowed to optimize field
> > > references based on type; so that:
> > >
> > > main()
> > > {
> > > union foo_t foo;
> > > void *vp;
> > >
> > > foo.i = 5;
> > > foo.p = 0;
> > >
> > > if(foo.i) {
> > > printf("true\n");
> > > } else {
> > > printf("false\n");
> > > }
> > > }
> > >
> > > may, depending on the optimizer, print either true or false. Technically,
> > > this is an invalid ANSI C program.
> >
> > I never saw that, and I think you may be wrong, so if you have the ansi
> > standard lying around, give me a quote, ok? Harbison & Steele says, on
> > page 132-133, that doing what you said above is non-portable (I agree),
> > but programmers "sometimes do this to 'reach under' C's type system
> > ...". There was more, but I'm sure you know it already.
> >
> >
>
> It's in there; believe me (I'm the manager for C/C++ compiler development
> at SAS Institute...)
>
> The ANSI C standard, section 3.3.2.4 says:
>
> "With one exception, if a member of a union object is accessed after
> a value has been stored in a different member of the object, the
> behaviour is implementation-defined."
And you _seem_ to have made my argument ... you said ANSI forbids it,
you even quoted yourself above, but your quotation from the standard
says it's implementation-defined. That means it's legal, but undefined
behavior. For any reasonable shop making software for sale, they may
mean the same thing, but for someone doing one-off controllers, the
operation is clearly legal, and the programmer is clearly warned that
they had better know what they're doing, because it's not going to be
portable.
I'm making a distinction between "forbids" (which I take to mean that
the compiler must catch it and cause a fatal error) and "non-portable"
(which I take to mean that any reasonable compiler should issue a
warning, and no public shop should use).
That's my argument, if that's wrong, then I'm completely wrong.
>
> [The exception is to allow for a "common initial sequence" in which
> the union contains structures whose first fields are compatible types.
> We're note dealing with compatible types, or structures, in this
> example, so the exception clearly does not apply.]
>
> Furthermore, section 3.3 specifies:
>
> "An object shall have its stored value accessed only by an lvalue
> that has one of the following types:
>
> o) The declared type of the object
> o) a qualified version of the declared type of the object
> o) a type that is the signed or unsigned type corresponding to the
> declared type of the object
> ...
>
> The point of this particular definition (per the footnote in the
> standard) is to list exactly when an object may be considered to be
> aliased.
>
> This, the following code is non-ANSI, and may produce surprising
> results:
>
> char *cp;
> int i;
>
> i = 5;
> cp = (char *)&i;
> *cp = 0x80; /* 'i' is being incorrectly referenced */
> printf("i is 0x%x", i);
>
> An ANSI conforming implementation would be correct in generating the
> output
> i is 5
> as the compiler, per the rules above, doesn't have to note the aliasing
> that occured when the stored value of 'i' was incorrectly referenced.
>
> In fact, the entire purpose of the list in section 3.3 of the standard
> is to allow optimizers to do just that (type based aliasing) which
> can be a big win for code generation.
>
> - Dave Rivers -
>
>
>
>
----------------------------+-----------------------------------------------
Chuck Robey | Interests include any kind of voice or data
chuckr@glue.umd.edu | communications topic, C programming, and Unix.
213 Lakeside Drive Apt T-1 |
Greenbelt, MD 20770 | I run Journey2 and picnic (FreeBSD-current)
(301) 220-2114 | and jaunt (NetBSD).
----------------------------+-----------------------------------------------
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.00.9808042107000.409-100000>
