C++ 堆上的double是否总是8字节对齐?
从阅读各种其他堆栈溢出问题来看,C++ 堆上的double是否总是8字节对齐?,c++,alignment,C++,Alignment,从阅读各种其他堆栈溢出问题来看,double值有时可能仅为4字节对齐,而不是8字节对齐(因此存在GCC的-malign double)。这适用于堆和堆栈吗 在我看来,如果堆上的double值不总是8字节对齐,那么就不可能使用double*值执行指针算术,因为将double*值递增8字节,但是两个任意的double*值之间的差异可能不是8字节的倍数 如果您对我感兴趣的用例感到好奇,我有如下建议: #include <iostream> #include <iostream>
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;
}
#包括
#包括
#包括
结构EmptyBase1
{
};
结构EmptyBase2
{
};
结构点:public-EmptyBase1,public-EmptyBase2
{
双x;
双y;
双z;
};
int main(){
标准:向量点(10);
int stride=&点[1]。x-&点[0]。x;
std::cout从3.7.3.1我们了解了分配函数返回的指针应适当对齐,以便可以将其转换为任何完整对象类型的指针,然后用于访问分配的存储中的对象或数组。
。所有这些都说明它必须针对硬件进行适当对齐。因此,您可以不存在对齐约束且双精度
可以通过新
进行字节对齐的硬件
您的减法是不合法的,因为这两个double不是double
s的同一数组/连续块的一部分。但是重新解释到char*
的地址,然后减去这些指针应该是完全合法的。但是,您试图解决的真正问题是什么呢
编辑:正如在一篇评论中指出的那样,我现在实际上相当确定,即使转换为char*
并执行减法也是非法的。即使它没有在8字节边界上对齐,它不是仍然是连续的吗?连续内存应该保证有效的指针算法。只有在两个指针同时存在的情况下,减去两个指针才是定义良好的指向同一数组的元素(或超过末尾的元素)。指向数组元素的子对象的指针不计算在内,即使内存是“连续的”。不过,谁知道,它可能在VS上工作,这对于您的目的可能已经足够好了。新t
自然对齐,但您可能有未对齐的类型(使用包装指令或重新解释铸件
)@Brian:我不知道指针减法的限制,这正好回答了我的问题。这在标准中有什么地方吗?我只提到了VS,因为它是唯一一个与多个基类有关的问题;我确实需要我的代码能够跨多个编译器和平台移植。@IanMackenzie[解释添加]/6.我可能确实必须按照您的建议执行char*
减法-我希望避免这种情况。我目前有一个MatrixView
类,用于允许对内存中任意double
值块执行矩阵运算。它目前实现为指向第一项的指针、行计数、列计数和列数n跨距。列跨距当前存储为整数指针偏移量。我希望能够构造一个有效的矩阵视图
,指向std::vector
中的组件数据,但听起来我必须将列跨距改为字节。我不认为转换为char*
是magiCaly将消除指针算法仅在数组内部有效的要求。经典示例是8086,其中数组仅限于一个段,指针算法不考虑段边界。也许-但至少在我的情况下,所有的双精度都在同一个数组中,它恰好是一个P的数组oint
对象而不是double数组。在这种情况下,您是否可以看到各种double组件之间基于char*
的指针算法无效?