我正在尝试找出我的64位计算机(Intel iCore7上为Win10)上的对齐方式。我想到了这个实验:
void check_alignment(char c1, char c2 )
{
printf("delta=%d\n", (int)&c2 - (int)&c1); // prints 4 instead of 8
}
void main(){
check_alignment('a','b');
}
我期待的是 delta=8
。由于它是64位计算机, char c1
和 char c2
应该以8的倍数存储。不是吗?
即使我们假设编译器已经进行了优化,以将它们存储在较小的空间中,为什么不直接将它们重新存储为 delta=1
?为什么要对齐4个字节?
我用 float
类型重复了上述实验,但仍然给出了 delta=4
void check_alignment(float f1, float f2 )
{
printf("delta=%d\n", (int)&c2 - (int)&c1); // prints 4
}
void main(){
check_alignment(1.0,1.1);
}
答案 0 :(得分:6)
首先,如果您的平台是64位的,那么为什么要将指针值转换为int
? int
在您的平台上是否为64位宽?如果没有,那么减法可能会产生毫无意义的结果。为此,请使用intptr_t
或ptrdiff_t
,而不是int
。
第二,在典型的实现中,无论您的平台是否为64位,通常将1字节类型对齐1字节边界。要查看8字节对齐方式,您需要8字节类型。为了查看其对齐方式,您必须检查地址的物理值(即是否可以被1、2、4、8等整除),而不要分析两个变量的间隔距离。
第三,c1
和c2
在内存中的距离与char
类型的对齐要求无关。由char
值如何在您的平台上传递(或本地存储)确定。在您的情况下,它们显然每个分配了4字节的存储单元。很好没有人会向您保证两个不相关的1字节对齐对象将尽可能紧密地排在一起。
如果要通过测量两个对象之间的存储距离来确定对齐方式,请声明一个数组。不要尝试测量两个独立对象之间的距离-这是没有意义的。
答案 1 :(得分:5)
要确定C实现中最大的基本对齐方式,请使用:
#include <stdio.h>
#include <stddef.h>
int main(void)
{
printf("%zd bytes\n", _Alignof(max_align_t));
}
要确定任何特定类型的对齐要求,请用该类型替换上面的max_align_t
。
对齐并非纯粹是处理器或其他硬件的功能。硬件可能支持具有不同性能影响的对齐或不对齐访问,某些指令可能支持不对齐访问,而另一些则不支持。特定的C实现可能结合使用或不使用各种指令来选择是否需要某些对齐方式。此外,在某些硬件上,操作系统是否可以配置是否支持不对齐访问。