c - 64位机器中的对齐不是8字节

标签 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 c1char 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);
}

最佳答案

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

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

第三,c1c2在内存中的距离与char类型的对齐要求关系不大。它取决于 char 值在您的平台上传递(或本地存储)的方式。在您的情况下,它们显然每个都分配了 4 字节存储单元。那就完全没问题了。没有人向您保证两个具有 1 字节对齐的不相关对象将尽可能紧密地彼此相邻打包。

如果您想通过测量两个对象存储的距离来确定对齐方式,请声明一个数组。不要尝试测量两个独立物体之间的距离 - 这是没有意义的。

关于c - 64位机器中的对齐不是8字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51622751/

相关文章:

c - 网络编程中如何完成tcp拆解的完整4步

c - 在 C 中重新分配字符串数组?段错误

c - 为什么在 MSP430-GCC 中优先使用 int 而不是 (unsigned) char 作为小整数

检查应用程序是否对进程句柄具有给定的访问权限

c++ - 为什么语言的简单性和执行时间之间似乎存在紧张关系?

java - 我找不到 javaC.sublime-build

c++ - -Ofast 在使用 long double 时产生不正确的代码

cpu-architecture - RISC-V : Why set least significant bit to zero in JALR

c - C 结构中的信号量 (sem_t) 是否已填充以尊重对齐?

c - GCC 兼容多种架构的最高指令集