tags:

views:

296

answers:

1

What is the basic usage of std::tr1::aligned_storage ? Can it be used as auto memory for a data type Foo like the one below?

   struct Foo{...};
   std::tr1::aligned_storage<sizeof(Foo)
     ,std::tr1::alignment_of<Foo>::value >::type buf;
   Foo* f = new (reinterpret_cast<void*>(&buf)) Foo();
   f->~Foo();

If so, what about storing multiple Foo in the buf like,

    std::tr1::aligned_storage<5*sizeof(Foo)
         ,std::tr1::alignment_of<Foo>::value >::type buf;
    Foo* p = reinterpret_cast<Foo*>(&buf);
    for(int i = 0; i!= 5; ++i,++p)
    {
     Foo* f = new (p) Foo();
    }

Are they valid programs? Is there any other use case for it ? Google search only yields the documentation about aligned_storage, but very little about the usage of it.

+2  A: 

Well, apart from your use of reinterpret_cast, it looks ok to me. (I'm not 100% sure on the second one).

The problem with reinterpret_cast is that it makes no guarantees about the result of the cast, only that if you cast the result back to the original type, you get the original value. So there is no guarantee that the result of the cast will contain the same bit pattern, or point to the same address.

As far as I know, a portable solution for casting a pointer x to a type T* is static_cast<T*>(static_cast<void*>(x)), since static_cast to and from void* is guaranteed to turn a pointer to the same address.

But that's only tangentially related to your question. :)

jalf
abir
yeah, I don't know of a compiler where reinterpret is actually a problem (and I think they're going to make it work as you'd expect in C++0x), but according to the standard, it is undefined behavior. The static_cast trick should work for any pointer type.
jalf
`template<typename T> T pointer_cast(void* p) { return static_cast<T>(p); }`. That, plus the const overload version (`const void* p`), will save some typing. Boost has similar functions, `static_pointer_cast` and `dynamic_pointer_cast`.
Logan Capaldo
actually, in the current as-well as in the (draft) C++1x standard, `reinterpret_cast` to or from `void*` isn't allowed (in spite of implementations allowing it). so you really should use `static_cast`. In C++1x, for standard layout types, `reinterpret_cast<T*>(u)` is defined in terms of `static_cast<T*>(static_cast<void*>(u))`.
Johannes Schaub - litb