开发者

How can I simulate alignas(T)?

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 T is a standard-layout and union is well formed, then

union
{
   T t;
   char memory[sizeof T];
};

should be aligned.


Either allocate the memory on the heap (which has the alignment guarantee) or use boost::aligned_storage.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜