In C++03 code, how would I portably implement an unsigned char[sizeof(T)]
buffer that has the same size and alignment as that of a given type T
?
For example:
template<class T>
void test()
{
unsigned char buffer[sizeof(T)]; // <----- how do I ensure this is aligned?
if (some_condition())
{
T *const obj = new(buffer) T();
// ...
obj->~T();
}
else { /* use 'buffer' for something else */ }
}
Is this even possible, or are you forced to use compiler extensions in order to implement this?
In his Guru Of The Week #28 column, Herb Sutter uses a union but it's less robust than Boost's efforts.
Boost's aligned_storage solves the gory details for you. If you look at its implementation, you'll see it uses MSCV's __alignof
or GCC's __alignof__
as well as another template: type_with_alignment
.
From my own codebase, I once used (derived from the GOTW link above):
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706)
# pragma warning(push)
# pragma warning(disable: 4371)
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706)
union AlignedStorage
{
char storage[sizeof(T)];
int16 dummy0;
int32 dummy1;
int64 dummy2;
float dummy3;
double dummy4;
long double dummy5;
void (*dummy6)();
struct dummy7;
int dummy7::*dummy8;
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215)
# pragma warning(push)
# pragma warning(disable: 4121)
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215)
int (dummy7::*dummy9)(int);
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215)
# pragma warning(pop)
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215)
}; // AlignedStorage
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706)
# pragma warning(pop)
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706)
These days I would just rely on Boost since it likely covers many more corner cases and compiler specificities