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.

> 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

Reply via email to