On 11/12/08, James Dennett <[EMAIL PROTECTED]> wrote: > On Wed, Nov 12, 2008 at 11:29 AM, Joe Buck <[EMAIL PROTECTED]> wrote: > > On Tue, Nov 11, 2008 at 08:43:40PM -0800, James Dennett wrote: > >> (There are secondary uses of unions for type punning. Most such uses > >> are not valid portable C++, but g++ supports them because they're so > >> common in real code.) > > > > On the contrary: the uses of unions for type-punning, while not portable, > > are valid C++, and while not portable, the behavior is > > implementation-defined (because it exposes the bitwise implementation of C > > and C++ types). > > > Interesting that you call them "valid C++" when the standard leaves > them as undefined behavior (not just implementation-defined). As I > implied, there are some permitted uses of type punning in unions, but > they're quite restricted. > > Let's be concrete: > > union { > int i; > double d; > } u; > > u.i = 1; > u.d = 2.0; > > printf("%d\n", u.i); > > AIUI, the printf() statement above has undefined behavior, and might > quite possibly print 1, if the compiler uses the knowledge that reads > from u.i cannot be affected (in code with defined behavior) by writes > to u.d. Indeed, the write to u.d above might reasonably be eliminated > by the optimizer if u.d is never read subsequently. > > Placing most types inside a union doesn't make it any more valid to > alias them than if reinterpret_cast<int*>(&d) were used on a double d.
Now would be a good time to mention Google's bit_cast<>. > > > > Without this feature, it would not be possible to > > implement a function like ldexp or frexp in C or C++, where we want > > to consider the same storage either as a double or as a sequence of > > bytes. > > > It's possible to do that without using unions; pointers to character > types are explicitly permitted to alias any storage. > > > -- James > -- Lawrence Crowl