堆上的双打总是8字节对齐吗?

时间:2014-07-29 18:13:20

标签: c++ alignment

通过阅读各种其他Stack Overflow问题,似乎double值有时可能只是4字节对齐而不是8(因此存在GCC的-malign-double)。这适用于堆还是堆栈?

在我看来,如果堆上的double值并不总是8字节对齐,那么由于递增double*,因此无法使用double*值执行指针运算将它提前8个字节,但两个任意double*值之间的差异可能不是8个字节的倍数。

如果您对我感兴趣的用例感到好奇,我会有类似的事情:

#include <iostream>

#include <iostream>
#include <vector>

struct EmptyBase1
{
};

struct EmptyBase2
{
};

struct Point : public EmptyBase1, public EmptyBase2
{
    double x;
    double y;
    double z;
};

int main() {
    std::vector<Point> points(10);
    int stride = &points[1].x - &points[0].x;
    std::cout << stride << std::endl;
    return 0;
}

在这种情况下,Visual Studio并未完全应用空基类优化(请参阅https://stackoverflow.com/a/12714226/953078),因此无法保证sizeof(Point) == 3 * sizeof(double)stride是否始终保证在&points[1].x&points[2].x&points[5].y&points[4].y等之间提供有效的内存偏移量?

1 个答案:

答案 0 :(得分:1)

从3.7.3.1开始,我们了解了分配函数The pointer returned shall be suitably aligned so that it can be converted to a pointer of any complete object type and then used to access the object or array in the storage allocated。所有这些都表明它必须与硬件适当对齐。因此,您可以设想没有对齐约束的硬件,并且double可以从new字节对齐。

您的减法是不合法的,因为两个双精度数不是double s的同一数组/连续数据块的一部分。但是reinterpret_cast地址char*然后减去那些指针应该是完全合法的。但是你想解决什么真正的问题?

编辑:正如评论中所指出的,我现在实际上相当确定甚至转换为char*并进行减法是非法的。