64位系统上的指针是否仍然是4字节对齐(类似于32位系统上的双精度)?或者他们注意8字节对齐?
例如,在64位系统上,以下数据结构有多大:
struct a {
void* ptr;
char myChar;
}
指针是否会被8字节对齐,导致字符的填充为7个字节(总计= 8 + 8 = 16)?或者指针是4字节对齐(4字节+4字节)导致3个字节的填充(总计= 4 + 4 + 4 = 12)?
谢谢, 莱恩
答案 0 :(得分:6)
我认为你不能依赖任何严格的规则。我认为这是您使用的编译器和您选择的编译选项的函数。
最好的办法是编写一个程序来测试这个并吐出一个头文件,将对齐规则编成#define
s。您也可以在宏中计算您感兴趣的内容。
答案 1 :(得分:6)
数据对齐和打包是特定于实现的,通常可以从编译器设置(甚至是编译指示)进行更改。
但是假设您使用默认设置,在大多数(如果不是全部)编译器上,结构总共应该是16个字节。原因是计算机读取的数据块大小为其本机字大小(在64位系统中为8个字节)。如果要将其填充到4字节偏移量,则下一个结构将无法正确填充到64位边界。例如,在arr [2]的情况下,数组的第二个元素将以12字节偏移量开始,该偏移量不在机器的本地字节边界处。
答案 2 :(得分:3)
通常在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位系统的例子。
答案 3 :(得分:1)
语言标准没有关于填充的陈述。对齐规则是特定于平台的(即,您必须在PowerPC CPU上以不同于x86_64 CPU的方式对齐),并且它们是实现定义的,这意味着您的编译器可以执行任何工作(并且可能使用不同的命令更改该行为) -line选项或版本更新后。)
我坚信任何建议都是“这是通常这个或那个”是误导性的,也可能是危险的。
您可以编写一个测试程序来执行几个sizeof()
和/或offsetof()
语句,并为您编写一个包含#define
个标题的标题,说明所使用的填充。
您可以使用autoconf
为您执行此操作。
至少,您应该在assert( sizeof( ... ) )
函数的开头添加main()
语句,以便在您的假设出错时获得通知。
答案 4 :(得分:0)
您需要查阅您感兴趣的特定ABI的文档。例如,这里是the System V ABI x86-64 architeture supplement - 您可以在第12页看到此ABI上的指针是8字节对齐的(是的,您显示的结构将填充为16个字节。)