问题 C 64位指针对齐


64位系统上的指针是否仍然是4字节对齐(类似于32位系统上的双精度)?或者他们注意到8字节对齐?

例如,在64位系统上,以下数据结构有多大:

struct a {
    void* ptr;
    char myChar;
}

指针是否会被8字节对齐,导致7个字节的填充(字符总数= 8 + 8 = 16)?或者指针是4字节对齐(4字节+4字节)导致3字节的填充(总= 4 + 4 + 4 = 12)?

谢谢, 瑞安


4053
2018-03-24 07:10


起源

有一会儿,我读了“C64”。 - Thilo


答案:


数据对齐和打包是特定于实现的,通常可以从编译器设置(甚至是编译指示)进行更改。

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


6
2018-03-24 07:32





我认为你不能依赖任何严格的规则。我认为这是您使用的编译器和您选择的编译选项的功能。

最好的办法是编写一个测试它的程序,然后吐出一个头文件,将对齐规则编成法典 #define秒。您也可以在宏中计算您感兴趣的内容。


6
2018-03-24 07:17





通常在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
2018-03-24 07:30





语言标准没有关于填充的陈述。对齐规则是特定于平台的(即,您必须在PowerPC CPU上以与在x86_64 CPU上不同的方式对齐),并且它们是实现定义的,这意味着您的编译器可以执行任何工作(并且可能使用不同的命令更改该行为) -line选项或版本更新后)。

我坚信这一点 任何 建议按照“这是 平时 这个或那个“有误导性,可能是危险的。

  1. 你可以写一个执行几个的测试程序 sizeof() 和/或 offsetof()语句并为您写一个标题包含一些 #define说明使用的填充物。

  2. 您可以使用 autoconf 为你做这件事。

  3. 至少,你应该添加 assert( sizeof( ... ) ) 在您的开头的陈述 main() 功能,以便在您的假设错误时获得通知。


1
2018-03-24 07:40





您需要查阅您感兴趣的特定ABI的文档。例如,这里是 System V ABI x86-64 architeture补充  - 你可以在第12页看到这个ABI上的指针是8字节对齐的(所以是的,你显示的结构将被填充到16个字节)。


0
2018-03-24 07:38