我如何模拟alignas(T)?

时间:2011-08-05 16:06:04

标签: c++ memory alignment memory-alignment

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

char memory[sizeof T];
.
.
.
new(memory) T(whatever);

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

alignas(T) char memory[sizeof T];

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

4 个答案:

答案 0 :(得分: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;

我还没有听说过,更不用说相遇了,上面的机器 不够。通常,只需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 ;
} ;

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

请注意,标准并未正式保证这一点。但它 将在实践中工作。

答案 1 :(得分:5)

通过Google搜索vc++ align显示this page:使用__declspec(align(#))

答案 2 :(得分:3)

如果T是标准布局并且联合格式良好,那么

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

应该对齐。

答案 3 :(得分:2)

分配堆上的内存(具有对齐保证)或使用boost::aligned_storage