Boost logo

Boost :

Subject: Re: [boost] gcc-4.4.0 and boost::optional is giving (spurious?) strict-aliasing warnings
From: Fernando Cacciola (fernando.cacciola_at_[hidden])
Date: 2009-05-15 15:11:04


Hi All,

Sorry but I just couldn't find time to answer this before.

> On Thu, May 7, 2009 at 3:37 AM, Kim Barrett <kab.conundrums_at_[hidden]> wrote:
>> At 7:17 PM -0300 5/5/09, Brad Spencer wrote:
>> In boost/aligned_storage.hpp, the class template
>> boost::aligned_storage defines its address member function thusly:
>>
>> void* address() { return this; }
>> const void* address() const { return this; }
>>
>
> I'm not 100% sure, but this could be very wrong as, IIRC, there is no
> guarantee that for non PODS the address of the first element (i.e.
> aligned_storage.data_) is the same as 'this'.
>
> but why doesn't aligned storage implements address() as:
>
> void * address { return this.data_.data_.buf; }
>
> BTW, I see that boost optional actually uses its own implementation of
> aligned storage,

Indeed.. whose code is not like the one above.

> whose address member function returns a pointer to a
> char buffer, so it shouldn't be a problem.
>
Precisely... a char* is explcitely allowed to alias any object, so, for
Boost.Optional at least, the warning is clearly spurious.

>> There is code in boost/optional/optional.hpp (and probably the other
>> libs you mention) which looks like:
>>
>> internal_type* get_object() {
>> return static_cast<internal_type*>(m_storage.address());
>> }
>>
>> What this leads, after some expansion, to something roughly equivalent
>> to
>>
>> static_cast<internal_type*>(
>> static_cast<void*>(
>> <a pointer to an instance of aligned_storage> ))
>>
Not in the case of optional. It is:

    static_cast<internal_type*>(
         static_cast<void*>(
             <a char*> ))

which should not raise any strict aliasing warnings

>> which I believe is not strict aliasing safe. It is effectively a cast
>> from aligned_storage* to internal_type*, with a trip through void*
>> along the way. That trip through void* does not make the conversion
>> satisfy the strict aliasing rules.
>>
>
> IIRC aliasing rules talk about dynamic types of objects: roughly, you
> can access a memory location only with a type which is the same as the
> *dynamic type* of that location or as a char array.
>
> Boost optional does an explicit placement new of the stored type on
> the buffer

Via a char*, so the placement new is merely taking the address of a suitably
aligned memory block.

> which changes the dynamic type of the buffer

Just for the record, no it doesn't.

Best

--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk