我将如何在C++03中便携地实现对齐堆栈存储

How would I portably implement aligned stack storage in C++03?

本文关键字:实现 对齐 存储 堆栈 C++03      更新时间:2023-10-16

在C++03代码中,如何可移植地实现与给定类型T具有相同大小和对齐方式的unsigned char[sizeof(T)]缓冲区?

例如:

template<class T>
void test()
{
    unsigned char buffer[sizeof(T)];   // <----- how do I ensure this is aligned?
    if (some_condition())
    {
        T *const obj = new(buffer) T();
        // ...
        obj->~T();
    }
    else { /* use 'buffer' for something else */ }
}

这是可能的吗?或者你被迫使用编译器扩展来实现这一点吗?

在他的《本周大师》第28期专栏中,Herb Sutter使用了一个联合,但它不如Boost的努力那么强大。

Boost的aligned_storage为您解决了血腥的细节。如果您查看它的实现,您会发现它使用MSCV的__alignof或GCC的__alignof__以及另一个模板:type_with_alignment

从我自己的代码库中,我曾经使用过(源自上面的GOTW链接):

#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706)
#  pragma warning(push)
#  pragma warning(disable: 4371)
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706)
      union AlignedStorage
      {
        char        storage[sizeof(T)];
        int16       dummy0;
        int32       dummy1;
        int64       dummy2;
        float       dummy3;
        double      dummy4;
        long double dummy5;
        void        (*dummy6)();
        struct      dummy7;
        int         dummy7::*dummy8;
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215)
#  pragma warning(push)
#  pragma warning(disable: 4121)
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215)
        int         (dummy7::*dummy9)(int);
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215)
#  pragma warning(pop)
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215)
      }; // AlignedStorage
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706)
#  pragma warning(pop)
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706)

现在我只依赖Boost,因为它可能涵盖更多的角落案例和编译器特性

__alignof__attribute__((aligned(n))这样的编译器扩展之所以存在,是因为在C和C++中无法方便地实现确定和强制对齐。也就是说,这个标准不需要任何手段。