|
Boost : |
Subject: Re: [boost] aligned_storage in unions
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2010-09-22 18:02:23
----- Original Message -----
From: "Larry Evans" <cppljevans_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Wednesday, September 22, 2010 11:38 PM
Subject: Re: [boost] aligned_storage in unions
> On 09/22/10 15:28, Frank Mori Hess wrote:
>> On Wednesday 22 September 2010, Larry Evans wrote:
>>> On 09/22/10 14:04, Frank Mori Hess wrote:
>>
>>>> I don't see how that gets around the anti-aliasing rules. The compiler
>>>> is allowed to assume incompatible pointers won't _ever_ alias. So just
>>>> because your program does things in a certain order doesn't mean the
>>>> compiler isn't allowed to use the anti-aliasing assumptions to reorder
>>>> things in a nasty way. Couldn't it look at the destruction of the old
>>>> object and the construction of the new object as two completely
>>>> independent actions it is free to reorder or interleave?
>>
>>> I hadn't thought of the compiler reordering the calls.
>>> Just to be clear, the compiler, using the anti-aliasing rules,
>>> could reorder:
>>
>>> 316 destroy();
>>> 317 assign_copy(from);
>>
>>> to:
>>
>>> 317 assign_copy(from);
>>> 316 destroy();
>>
>>> ? Or maybe just do everything in destroy before the lhs->~Lhs() call,
>>> then execute assign_copy(from) and then do lhs->~Lhs(). Hmm...
>>> OK, I think I got it, but am surprised.
>>
>> I think so, in principle. I only have a vague idea of what optimizing
>> compilers actually do under the hood though, which is why I tend to be very
>> conservative about obeying the strict aliasing rules (they've bitten me
>> before).
>>
>
> A more concrete example is attached.
>
> IOW, the strict aliasing rules would allow the compiler to move:
>
> p20->~str();
>
> after the:
>
> str<10>* p10=new(buf) str<10>;
>
> because p20 and p10 are assumed not pointing to the same
> location.
>
> Note: I did compile with:
>
> -O3 -Wstrict-aliasing
>
> as Mathias suggested; however, the compiler didn't issue any
> warnings. I'm wondering why?
Hi,
I don't know which version are you using, but the options differ from aversion to another.
4.1.2
-Wstrict-aliasing
This option is only active when -fstrict-aliasing is active. It warns about code which might break the strict aliasing rules that the compiler is using for optimization. The warning does not catch all cases, but does attempt to catch the more common pitfalls. It is included in -Wall.
-Wstrict-aliasing=2
This option is only active when -fstrict-aliasing is active. It warns about code which might break the strict aliasing rules that the compiler is using for optimization. This warning catches more cases than -Wstrict-aliasing, but it will also give a warning for some ambiguous cases that are safe.
4.5
-Wstrict-aliasing
This option is only active when -fstrict-aliasing is active. It warns about code which might break the strict aliasing rules that the compiler is using for optimization. The warning does not catch all cases, but does attempt to catch the more common pitfalls. It is included in -Wall. It is equivalent to -Wstrict-aliasing=3
-Wstrict-aliasing=n
This option is only active when -fstrict-aliasing is active. It warns about code which might break the strict aliasing rules that the compiler is using for optimization. Higher levels correspond to higher accuracy (fewer false positives). Higher levels also correspond to more effort, similar to the way -O works. -Wstrict-aliasing is equivalent to -Wstrict-aliasing=n, with n=3.
Level 1: Most aggressive, quick, least accurate. Possibly useful when higher levels do not warn but -fstrict-aliasing still breaks the code, as it has very few false negatives. However, it has many false positives. Warns for all pointer conversions between possibly incompatible types, even if never dereferenced. Runs in the frontend only.
Level 2: Aggressive, quick, not too precise. May still have many false positives (not as many as level 1 though), and few false negatives (but possibly more than level 1). Unlike level 1, it only warns when an address is taken. Warns about incomplete types. Runs in the frontend only.
Level 3 (default for -Wstrict-aliasing): Should have very few false positives and few false negatives. Slightly slower than levels 1 or 2 when optimization is enabled. Takes care of the common pun+dereference pattern in the frontend: *(int*)&some_float. If optimization is enabled, it also runs in the backend, where it deals with multiple statement cases using flow-sensitive points-to information. Only warns when the converted pointer is dereferenced. Does not warn about incomplete types.
HTH,
Vicente
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk