RFA and RFC: tweak -fstrict-aliasing docs, provide pointer-cast example
Gabriel Dos Reis
gdr@integrable-solutions.net
Wed Jun 25 15:35:00 GMT 2008
On Wed, Jun 25, 2008 at 9:49 AM, Andrew Haley <aph@redhat.com> wrote:
> Richard Guenther wrote:
>> On Wed, Jun 25, 2008 at 4:04 PM, Andrew Haley <aph@redhat.com> wrote:
>>> Hans-Peter Nilsson wrote:
>>>>> Date: Tue, 24 Jun 2008 10:36:15 +0100
>>>>> From: Andrew Haley <aph@redhat.com>
>>>>> 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.
>
More information about the Gcc-patches
mailing list