我如何模拟alignas(T)?

fre*_*low 6 c++ memory alignment memory-alignment

我有一个数组,用作类型对象的底层内存T:

char memory[sizeof T];
.
.
.
new(memory) T(whatever);
Run Code Online (Sandbox Code Playgroud)

如何确保对象memory正确对齐T?在C++ 0x中我可以说:

alignas(T) char memory[sizeof T];
Run Code Online (Sandbox Code Playgroud)

但Visual Studio 2010尚不支持该特定功能.

Jam*_*nze 10

通常的(可移植的)解决方案是将内存声明与任何内置类型组合在一起,T需要最大的对齐.最简单的方法是使用与所有可能候选人的联盟:

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;
Run Code Online (Sandbox Code Playgroud)

我还没有听说过,更不用说遇到一台机器了,上面还不够.一般来说,double就够了.(在英特尔和Sparc上这绝对足够了.)

在某些极端情况下,这可能导致分配比必要更多的内存,例如,如果T只包含一个或两个char.大多数时候,这确实没关系,并且不值得担心,但如果是,可以使用以下内容:

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 ;
} ;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,MaxAlignFor<T>永远不会大于T (并且要有足够的对齐,因为所需的对齐永远不会大于大小T).

请注意,标准不能正式保证这一点.但它会在实践中发挥作用.


Meh*_*dad 5

谷歌搜索vc++ align显示此页面:使用__declspec(align(#)).

  • 其中,正如前面的`__`明确指出的那样,是编译器特定的扩展. (4认同)