我的理解是,如果您希望数组对齐,则必须明确指定数组的对齐方式。
但是,我声明的 float 组似乎总是对齐到 16 字节。
float *ptr1 = new float[1];
cout<<"ptr1: "<<ptr1<<endl;
float *ptr2 = new float[3];
cout<<"ptr2: "<<ptr2<<endl;
float arr1[7];
cout<<"arr1: "<<arr1<<endl;
float arr2[9] __attribute__((aligned(2)));
cout<<"arr2: "<<arr2<<endl;
这是输出
ptr1: 0x13dc010
ptr2: 0x13dc030
arr1: 0x7fff874885c0
arr2: 0x7fff87488590
这是有原因的吗?我正在使用 gcc 4.6.3
但是,如果它是一个指向浮点位置的指针或静态分配的,我看不到它
static float arr3[9] __attribute__((aligned(2)));
cout<<"arr3: "<<arr3<<endl;
float *x;
cout<<"x: "<<x<<endl;
输出:
arr3: 0x4030b2
x: 0x7fff8c7dd9e8
此代码在 x64 上运行。
最佳答案
对齐要求由每个编译器决定,受硬件要求和任何相关的影响ABI .
C 和 C++ 语言讨论了类型的对齐方式,但它们没有强加任何特定要求(除了,例如,结构的对齐方式至少是其任何成员的对齐方式)。一个有效的实现可以允许所有数据类型按字节对齐,或者它可以要求每个标量类型按其自身的大小对齐(后者更常见)。中间对齐是可能的,例如在 4 字节边界上对齐 8 字节类型。
特别是在 x86 上,将标量与其大小对齐可以提高访问效率,但未对齐的访问仍然可以正常工作,只是速度稍慢一些。
float
数组的要求 对齐方式与单个float
对象的要求对齐方式相同。如果 float
是 4 个字节,那么对齐不能超过 4 个字节,因为数组在它们的元素之间没有间隙。
如您(可能)所见,特定的编译器可能会选择对数组对象施加更严格的对齐方式,如果它能使访问这些对象的效率更高一些的话。
如果 new
运算符是通过调用 malloc
实现的,那么所有 new
分配的对象都将具有对任何类型都足够严格的对齐方式.
如果 float
数组始终与 16 字节边界对齐,那是因为您的编译器选择以这种方式分配它们,而不是因为语言要求这样做。另一方面,如果您使用别名将 float
数组强制为 4 字节对齐(假设 sizeof (float) == 4
),则访问该数组及其元素仍应正常工作。
顺便说一句,当我在我的 x86_64 系统上运行您的代码(将其包装在 main
程序中之后)时,我得到的结果与您的类似。当我在 x86 系统上运行它时,我得到:
ptr1: 0x9e34008
ptr2: 0x9e34018
arr1: 0xbfefa160
arr2: 0xbfefa17c
我在两个系统上都在 Linux 下使用 gcc。
所以对您的问题的直接回答是否定的,float
数组并不总是与 16 字节边界对齐。
但在大多数情况下,您没有特别需要关心的理由。除非您使用别名技巧(将某个已声明类型的对象视为另一种类型),否则编译器总是至少为每个对象提供正确访问所需的对齐方式。
关于c++ - float 组是否总是与 16 字节边界对齐?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20101406/