在64位计算机中对齐不是8个字节

时间:2018-07-31 22:04:35

标签: c compilation cpu-architecture

我正在尝试找出我的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);
}

2 个答案:

答案 0 :(得分:6)

首先,如果您的平台是64位的,那么为什么要将指针值转换为intint在您的平台上是否为64位宽?如果没有,那么减法可能会产生毫无意义的结果。为此,请使用intptr_tptrdiff_t,而不是int

第二,在典型的实现中,无论您的平台是否为64位,通常将1字节类型对齐1字节边界。要查看8字节对齐方式,您需要8字节类型。为了查看其对齐方式,您必须检查地址的物理值(即是否可以被1、2、4、8等整除),而不要分析两个变量的间隔距离。

第三,c1c2在内存中的距离与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实现可能结合使用或不使用各种指令来选择是否需要某些对齐方式。此外,在某些硬件上,操作系统是否可以配置是否支持不对齐访问。