如何模拟alignas(T)?

发布于 2024-11-28 06:38:56 字数 296 浏览 1 评论 0原文

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

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

如何确保 memoryT 正确对齐物体?在 C++0x 中我只能说:

alignas(T) char memory[sizeof T];

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

烟凡古楼 2024-12-05 06:38:57

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

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

九歌凝 2024-12-05 06:38:57

如果 T 是标准布局并且联合形成良好,则

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

应该对齐。

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

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

should be aligned.

喜爱纠缠 2024-12-05 06:38:57

要么在堆上分配内存(具有对齐保证),要么使用boost::aligned_storage。

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

梦里°也失望 2024-12-05 06:38:56

通常的(可移植的)解决方案是将内存声明与 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 就足够了。 (这绝对是
在 Intel 和 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 的大小)。

请注意,标准并没有正式保证这些。但它
将在实践中发挥作用。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文