Perhaps, but the gcc team and the gcc compiler clearly disagree with
your interpretation of the strict aliasing rules, and the C standards
committee /seems/ to be leaning towards disagreeing with you.
(Disagrees for the C programming language mind you, though I would
argue that C++ ought to adopt whatever reasonable resolutions that the
C committee comes to on the union DR and related issues.) See
http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_236.htm
The problem is not simple, and the current wording in both the
C and the C++ standard definitely guarantees some behavior that
I don't think the committee wanted to guarantee (and which
doesn't work in g++, and probably in other compilers as well).
Fundamentally, there are two issues which have to be addressed:
1. Some sort of type punning is necessary in low level code.
Historically, K&R favored unions for this (rather than
pointer casting). For various reasons, the C committee,
when formulating C90, moved in the direction of favoring
pointer casts. All strictly as "intent", since there's
nothing the standard can define with regards to modifying
some bits in a double through a pointer to an integral type
(for example). It's been a long time since I've been
involved in C standardization, so I don't know if the
committee has moved again. Both pointer casting and unions
are wide spread in C code, and from a QoI point of view,
I would expect both to work, the the caveats discussed
below. Anything else shows disdain for the user community.
2. Possible aliasing kills optimization. This is the
motivation behind restrict, and before that noalias; the
programmer declares that there will be no aliasing, and pays
the price if he makes a mistake. The rules also allow the
compiler to assume that pointers to different types (with
a number of exceptions) do not alias. Except when they do.
My own opinion here is that type punning using pointer casts
discussed in 1. should only hold when the aliasing mechanism
is visible in the function where the aliasing occurs. (I'm
not sure how to formulate this in standardese, but I think
this is what the C committee is trying to do.)
and the links for associated meeting minutes for the discussion of the
union DR. The C standards committee /seems/ to be leaning towards a
very naive aliasing rule, though of course I guess we'll have to wait
and see until they publish something definitive.
I haven't followed it at all closely, but the last time
I looked, the tendancy was to favor a rule which made the
aliasing clear; accessing members of a union was fine (as long
as the member read was the last member written), but only
provided all of the accesses were through the union members.
With regards to pointer casts, it's harder to specify, but in
the end, they don't have to; they only have to make the intent
sort of clear. Formally, accessing any union member except the
last written, or accessing an object except as an unsigned char
or its actual type is undefined behavior. And will remain so,
since it is impossible to define anything which could be valid
on all platforms. This means that formally, all type punning is
undefined behavior.
Or, of course, you
could go ask them for us as you actually know them in person (maybe?),
and perhaps you could get them to answer the few other pesky issues I
have about how a general purpose portable conforming pooling memory
allocator on top of malloc is supposed to work, or not work. It would
be nice.
If you ask on comp.std.c++, you'll get some feedback. Or
perhaps comp.std.c---I haven't looked there in ages, but IMHO,
this is a problem that C should resolve, and C++ should simply
accept the decision. There's absolutely no reason for the
languages to have different rules here.
To quote you: "In practice, however, reinterpret_cast becomes useless
if this doesn't work." I think that reinterpret_cast is largely
useless, (except for converting between pointer types and integer
types), especially when compiled under the default gcc options. AFAIK,
reinterpret_cast exists for platform dependent hackery (of which I've
had the pleasure to never need to hack), to convert between pointers
types and integer types, and convert pointer types to char pointer and
unsigned char pointer, and not much else.
The purpose of reinterpret_cast is to make very low level,
platform dependent hackery, necessary. I've used the equivalent
(in C) when implementing the standard C library, one one hand in
the implementation of malloc and free, and on the other in some
of the low level math functions like ldexp. I tend to avoid it
otherwise.
I stand by my original point that you really ought not read objects
through incorrectly typed lvalues, unless that incorrectly typed
lvalue is char or unsigned char, if you can at all help it, for
maximum portability and conformance.
As soon as you need reinterpret_cast, portability goes out the
window. It's strictly for experts, and only for very machine
dependent code, at the very lowest level.