On Wed, Jun 25, 2008 at 9:49 AM, Andrew Haley <[EMAIL PROTECTED]> wrote: > Richard Guenther wrote: >> On Wed, Jun 25, 2008 at 4:04 PM, Andrew Haley <[EMAIL PROTECTED]> wrote: >>> Hans-Peter Nilsson wrote: >>>>> Date: Tue, 24 Jun 2008 10:36:15 +0100 >>>>> From: Andrew Haley <[EMAIL PROTECTED]> >>>>> I thought cast-through-pointer-to-union didn't work and was already >>>>> disallowed; we've been around all this already. >>>> We also bless assignments through unions, and this could be >>>> argued as assigning through a union, albeit casted. >>>> >>>>> This patch of yours >>>>> already documents uncontroversial behaviour. >>>> That's what I hope, but the existence of that code together in >>>> an *else* clause of #ifdef YES_ALIAS by a well-known author >>>> makes it de-facto controversial IMHO. Note also that another >>>> maintainer thought the code to be valid; see the PR. >>> So I see. I'm pretty sure that the compiler's alias analysis won't >>> think it's valid, but I haven't checked. >> >> Right. It happily "mis-"optimizes it. And on a second thought I >> agree the construct is invalid. >> >>> Do we actually document anywhere that a C++-style type pun along the lines >>> of >>> >>> reinterpret_cast<T&>(x) >>> >>> will not work? I'm guessing it probably won't, and that the union trick >>> is the only thing we do support. >> >> This is not a "pun", it only re-interprets the pointer _value_, > > Which pointer? x is not of pointer type, and neither is T. > >> not what it points to. > > The C++ standard calls this a type pun, so -- with all due respect -- I'm
The C++ standard does not actually call it a type pun, but I think I understand what you mean. The mapping used by reinterpret_cast is implementation defined. But really, reinterpret_cast<T>(e) is almost close to C's crudest cast (T)e. So, people expect reinterpret_cast<T*>(integer) and reinterpret_cast<integer_type>(pointer) to work in reasonable ways. If we guarantee the meaning of float f = 1.3f; int = *(int*)&f; then we should guarantee the meaning of reinterpret_cast<int&>(f), and vice-versa. We should also guarantee the pointer mapping hinted at by Richard in a previous mail. Other than that, I'm not convinced yet that we need to add more guarantees by extrapolating from the exceptional union case. > going to believe it! The question is whether this will fall foul of gcc's > aliasing in the same way that a pointer cast does, and I think it will, > > Anyway, I just checked, and we do warn, but only at -O2: > > #include <iostream> > > int > main(char argc, char **argv) > { > double d = 99; > long m = reinterpret_cast<long&>(d); > > p.cc:7: warning: dereferencing type-punned pointer will break strict-aliasing > rules Note that the above construct is turned (by the C++ front-end) into *(long*)(&d) which elicits the typepunning warning. But I agree that we don't want to guarantee this is a defined behaviour. > > Not a problem, then. Yep. > > Andrew. >