what is the basic use of aligned_storage?
Asked Answered
S

1

11

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.

Stalwart answered 4/7, 2009 at 15:13 Comment(0)
D
9

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. :)

Detonate answered 4/7, 2009 at 15:23 Comment(7)
That is a good solution. static_cast to/from void* is OK,but is it also true for multiple static_cast like static_cast<T>(static_cast<void*>(x)) where x has a type? Then i will replace all of my cast from type X to type Y as two static_cast rather than one reinterpret_cast just to feel safer. (The compiler i use GCC & MSVC 9 doesn't do any harm for the reinterpret_cast, and i am not sure whey another will do so. But yes, i want to be on safer side :) )Stalwart
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.Detonate
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.Disarrange
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)).Science
Since you've judged reinterpret_cast to be problematic, can I ask why, and (trick question?) how else one would map aligned_storage to an actual type? And yes, in C++11, reinterpret_cast (for most if not all types) is equivalent to the chained static_casts.Stratagem
@Stratagem Because C++11 and answer dating back to 2009 don't mix very well.Detonate
Since that implies something has changed in the meantime, what have I missed?Stratagem

© 2022 - 2024 — McMap. All rights reserved.