【问题标题】:C 64-bit Pointer AlignmentC 64 位指针对齐
【发布时间】:2011-01-31 03:29:19
【问题描述】:

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

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

struct a {
    void* ptr;
    char myChar;
}

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

谢谢, 瑞恩

【问题讨论】:

  • 看了一会儿“C64”。

标签: c 64-bit alignment


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    我认为您不能依赖任何硬性规定。我认为这是您使用的编译器和您选择的编译选项的功能。

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

    【讨论】:

      【解决方案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 位系统的示例。

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

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

          1. 您可以编写一个测试程序,执行几个sizeof() 和/或offsetof()statements,并为您编写一个包含一些#defines 的标头,说明使用的填充。

            李>
          2. 您可以使用autoconf 为您执行此操作。

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

          【讨论】:

            猜你喜欢
            • 2012-06-12
            • 2017-08-16
            • 2016-08-01
            • 2012-06-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-20
            • 2013-01-11
            相关资源
            最近更新 更多