Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在C+中可移植地实现对齐堆栈存储+;03?_C++_Memory Alignment_Placement New - Fatal编程技术网

C++ 如何在C+中可移植地实现对齐堆栈存储+;03?

C++ 如何在C+中可移植地实现对齐堆栈存储+;03?,c++,memory-alignment,placement-new,C++,Memory Alignment,Placement New,在C++03代码中,如何可移植地实现与给定类型的缓冲区大小和对齐方式相同的无符号字符[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)

在C++03代码中,如何可移植地实现与给定类型的缓冲区大小和对齐方式相同的无符号字符[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 */ }
}
模板
无效测试()
{
无符号字符缓冲区[sizeof(T)];//~T();
}
else{/*使用'buffer'表示其他内容*/}
}
这是可能的,还是为了实现这一点,您不得不使用编译器扩展?

在他的专栏文章中,Herb Sutter使用了一个联合,但它不如Boost的努力强大

Boost为您解决了血淋淋的细节问题。如果你看一下它的实现,你会发现它使用了MSCV的
\uuuuu alignof
或GCC的
\uuuuuu alignof\uuuu
以及另一个模板:
键入带对齐的uu

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


这些天我只会依赖Boost,因为它可能涵盖了更多的细节和编译器特性

编译器扩展的原因,比如
\uuuu alignof
\uu属性((aligned(n))存在的是,在C和C++中,不可实现的确定和强制对齐。标准不需要这样做。

两个问题:(1)我首先问这是如何实现的。有没有一种可移植的方式来做它,或者它需要编译器扩展吗?(2)作为第二个模板参数(路线),我应该给它什么?编辑后#1--你是说它需要编译器扩展吗?编辑后#2--是的,我可以组合所有可能的类型以获得最大对齐度,但在许多情况下,这会过度对齐数据并浪费空间。我试图获得与类型相同的对齐度;而不是更多,而不是更少。要恢复对齐度,需要C++03编译器扩展f类型。如果你知道对齐方式,你可以使用类似于Boost的
type\u with\u alignment
(第一眼看到它就会发现实现并不简单)的模板,事实上
type\u with\u alignment
需要
\u is\u pod(T)
extension@Mehrdad:因此,将要对齐的类型与char[]进行并集。有趣的问题。+1感谢你记住手动点击析构函数(尽管我有点不知道你是如何通过
常量
。我真的需要复习一下我的
常量
位置)。@WhozCraig:谢谢。注意指针不是常量,指针本身是。:)是的,我刚刚看到了=可以假定对齐限制是提供的参数(模板或函数)吗(如
template
其中N是您所需的边界?我只是想知道如何使用缓冲区的大小及其开始和结束来将对象放置在正确的位置。@WhozCraig:不太可能,因为我怎么知道所需的边界是什么?我不确定您是否试图说它不是可移植实现的,或者它是否是EAL不能实现。你的意思是?C/C++标准只给编译器留下自由,至少所有的东西都必须与char对齐。在C++中,11对齐是标准的事实的一部分,对齐可能是可移植的,对于大多数现有的架构。@ MeordDad C++标准不需要这些设施,因此ExtE。标注。@DarioOO所有内容都必须至少与char对齐-是否可以少对齐?在C++11中,对齐是标准事实的一部分-对于C++98也是如此。不确定您想表达什么观点。
#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)