C语言64位指针对齐问题

14

在64位系统上,指针仍然是4字节对齐的吗(类似于32位系统上的double)?或者它们不是8字节对齐的吗?

例如,在64位系统上,以下数据结构的大小是多少:

struct a {
    void* ptr;
    char myChar;
}

指针是否会对齐到8字节,导致字符需要填充7个字节(总共=8 + 8 = 16)?还是指针会对齐到4字节(4字节+4字节),导致需要3个字节的填充(总共=4 + 4 + 4 = 12)?

谢谢, Ryan


11
有一瞬间,我读到了“C64”。 - Thilo
5个回答

7

数据对齐和打包是与实现相关的,并且通常可以通过编译器设置(甚至是指示符)进行更改。

然而,假设您正在使用默认设置,在大多数(如果不是全部)编译器上,结构应该总共占用16个字节。原因是因为计算机使用其本地字大小(在64位系统中为8个字节)的数据块来读取数据。如果将其填充到4字节的偏移量,则下一个结构将无法正确填充到64位边界。例如,在arr [2]的情况下,数组的第二个元素将从12字节偏移处开始,这不是计算机的本机字节边界。


6

我认为您不能依赖任何硬性规则。这取决于您使用的编译器和所选的编译选项。

最好的方法是编写一个程序来测试并输出一个头文件,其中将对齐规则编码为#define。您还可以直接在宏中计算您感兴趣的内容。


4

一般情况下在64位系统上:

struct a {
    void* ptr;      // size is 8 bytes, alignment is 8
    char myChar;    // size is 1 byte,  alignment is 1
                    // padding of 7 bytes so array elements will be properly aligned
}

总大小为16字节。

但这完全是实现定义的 - 我只是给出了一个在许多(大多数?)64位系统上可能成立的例子。


1
你需要查阅特定 ABI 的文档。例如,这里是System V ABI x86-64 架构补充 - 你可以在第12页看到该 ABI 上的指针是8字节对齐的(因此,是的,你展示的结构体会被填充到16字节)。

1

语言标准对填充没有任何规定。对齐规则是平台特定的(例如,在 PowerPC CPU 上必须与 x86_64 CPU 上不同),并且它们是实现定义的,这意味着您的编译器可以做任何有效的事情(并且可能会在不同的命令行选项或版本更新后更改该行为)。

我坚信沿着“通常是这样或那样”的任何建议都是误导性的,可能是危险的。

  1. 您可以编写一个测试程序,执行一些 sizeof() 和/或 offsetof() 语句,并为您编写一个包含使用的填充的一些 #define 的头文件。

  2. 您可以使用 autoconf 来为您完成此操作。

  3. 至少,您应该在 main() 函数的开头添加 assert(sizeof(...)) 语句,以便在您的假设错误时得到通知。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接