在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
数据对齐和打包是与实现相关的,并且通常可以通过编译器设置(甚至是指示符)进行更改。
然而,假设您正在使用默认设置,在大多数(如果不是全部)编译器上,结构应该总共占用16个字节。原因是因为计算机使用其本地字大小(在64位系统中为8个字节)的数据块来读取数据。如果将其填充到4字节的偏移量,则下一个结构将无法正确填充到64位边界。例如,在arr [2]的情况下,数组的第二个元素将从12字节偏移处开始,这不是计算机的本机字节边界。
我认为您不能依赖任何硬性规则。这取决于您使用的编译器和所选的编译选项。
最好的方法是编写一个程序来测试并输出一个头文件,其中将对齐规则编码为#define
。您还可以直接在宏中计算您感兴趣的内容。
一般情况下在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位系统上可能成立的例子。
语言标准对填充没有任何规定。对齐规则是平台特定的(例如,在 PowerPC CPU 上必须与 x86_64 CPU 上不同),并且它们是实现定义的,这意味着您的编译器可以做任何有效的事情(并且可能会在不同的命令行选项或版本更新后更改该行为)。
我坚信沿着“通常是这样或那样”的任何建议都是误导性的,可能是危险的。
您可以编写一个测试程序,执行一些 sizeof()
和/或 offsetof()
语句,并为您编写一个包含使用的填充的一些 #define
的头文件。
您可以使用 autoconf
来为您完成此操作。
至少,您应该在 main()
函数的开头添加 assert(sizeof(...))
语句,以便在您的假设错误时得到通知。