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>