I have an array which is used as the underlying memory of an object of type T
:
char memory[sizeof T];
.
.
.
new(memory) T(whatever);
How can I make sure memory
is aligned correctly for T
objects? In C++0x I could just say:
alignas(T) char memory[sizeof T];
but Visual Studio 2010 does not support that particular feature yet.
The usual (portable) solution is to put the memory declaration in a union with whatever built-in type in T
requires the most alignment.
The simplest way would be to use a union with all of the likely
candidates:
union MaxAlign
{
int i ;
long l ;
long long ll ;
long double ld ;
double d ;
void* p ;
void (* pf)() ;
MaxAlign* ps ;
} ;
union
{
MaxAlign dummyForAlignment;
unsigned char memory[sizeof(T)];
} rawT;
I've yet to hear about, much less encounter, a machine where the above
didn't suffice. Generally, just double
suffices. (It is definitely
sufficient on Intel and on Sparc.)
In some extreme cases, this can result in allocating more memory than
necessary, e.g. if T
only contains one or two char
. Most of the
time, this really doesn't matter, and isn't worth worrying about, but if
it is, the following can be used:
namespace MyPrivate {
template< typename T, bool isSmaller >
struct AlignTypeDetail ;
template< typename T >
struct AlignTypeDetail< T, false >
{
typedef T type ;
} ;
template< typename T >
struct AlignTypeDetail< T, true >
{
typedef char type ;
} ;
template< typename T, typename U >
struct AlignType
{
typedef typename AlignTypeDetail< U, (sizeof( T ) < sizeof( U )) >::type
type ;
} ;
}
template< typename T >
union MaxAlignFor
{
typename MyPrivate::AlignType< T, char >::type c ;
typename MyPrivate::AlignType< T, short >::type s ;
typename MyPrivate::AlignType< T, int >::type i ;
typename MyPrivate::AlignType< T, long >::type l ;
typename MyPrivate::AlignType< T, long long >::type ll ;
typename MyPrivate::AlignType< T, float >::type f ;
typename MyPrivate::AlignType< T, double >::type d ;
typename MyPrivate::AlignType< T, long double >::type ld ;
typename MyPrivate::AlignType< T, void* >::type pc ;
typename MyPrivate::AlignType< T, MaxAlign* >::type ps ;
typename MyPrivate::AlignType< T, void (*)() >::type pf ;
} ;
In this case, MaxAlignFor<T>
will never be bigger than T
(and to have sufficient alignment, since the required alignment will
never be larger than the size of T
).
Note that none of this is formally guaranteed by the standard. But it will work in practice.
Googling for vc++ align
shows this page: use __declspec(align(#))
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With