
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@verizon.net> 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