How can I simulate alignas(T)?

泄露秘密 提交于 2020-01-01 05:22:14

问题


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.


回答1:


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.




回答2:


Googling for vc++ align shows this page: use __declspec(align(#)).




回答3:


If T is a standard-layout and union is well formed, then

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

should be aligned.




回答4:


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



来源:https://stackoverflow.com/questions/6959261/how-can-i-simulate-alignast

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!