通过阅读各种其他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
等之间提供有效的内存偏移量?
答案 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*
并进行减法是非法的。