【问题标题】:Are POD types always aligned?POD 类型是否始终对齐?
【发布时间】:2010-09-10 18:00:10
【问题描述】:

例如,如果我声明一个 long 变量,我可以假设它总是在“sizeof(long)”边界上对齐吗? Microsoft Visual C++ 在线帮助这么说,但这是标准行为吗?

更多信息:

一个。可以显式创建未对齐的整数 (*bar):

char foo[5]

int * bar = (int *)(&foo[1]);

b.显然,#pragma pack() 只影响结构、类和联合。

c。 MSVC 文档指出 POD 类型与它们各自的大小对齐(但它总是或默认情况下,它是标准行为,我不知道)

【问题讨论】:

    标签: c++ c visual-c++


    【解决方案1】:

    正如其他人所提到的,这不是标准的一部分,而是由编译器来实现,因为它认为适合所讨论的处理器。例如,VC 可以轻松地为 ARM 处理器实现与 x86 处理器不同的对齐要求。

    Microsoft VC 实现了基本所谓的自然对齐,最大大小由#pragma pack 指令或/Zp 命令行选项指定。这意味着,例如,任何大小小于或等于 8 字节的 POD 类型都将根据其大小进行对齐。任何更大的都将在 8 字节边界上对齐。

    如果控制不同处理器和不同编译器的对齐很重要,则可以使用 1 的打包大小并填充结构。

    #pragma pack(push)
    #pragma pack(1)    
    struct Example
    {
       short data1;     // offset 0
       short padding1;  // offset 2
       long data2;      // offset 4
    };
    #pragma pack(pop)
    

    在这段代码中,padding1 变量的存在只是为了确保 data2 自然对齐。

    答案:

    是的,这很容易导致数据错位。在 x86 处理器上,这根本不会造成太大的伤害。在其他处理器上,这可能会导致崩溃或执行速度非常慢。例如,Alpha 处理器会抛出一个处理器异常,该异常会被操作系统捕获。然后,操作系统将检查指令,然后执行处理未对齐数据所需的工作。然后继续执行。 __unaligned 关键字可以在 VC 中用于标记非 x86 程序(即 CE)的未对齐访问。

    【讨论】:

      【解决方案2】:

      默认情况下,是的。但是,可以通过 pack() #pragma 更改它。

      我不相信 C++ 标准在这方面做出任何要求,并将其留给实现。

      【讨论】:

      • 哦,是的,我忘了打包选项/pragmas。
      • 也可以通过项目/编译器选项设置。
      【解决方案3】:

      C 和 C++ 不要求任何类型的对齐。但是 x86 强烈倾向于自然对齐,并且大多数其他 CPU 架构要求,并且编译器通常会尽最大努力让 CPU 满意。所以在实践中你不会看到编译器生成未对齐的数据,除非你真的扭曲它的手臂。

      【讨论】:

        【解决方案4】:

        是的,所有类型总是至少按照它们的对齐要求对齐。

        不然怎么办?

        但请注意,一个类型的 sizeof() 与其对齐方式不同。

        您可以使用以下宏来确定类型的对齐要求:

        #define ALIGNMENT_OF( t ) offsetof( struct { char x; t test; }, test )
        

        【讨论】:

        • 但是,在 Intel x86 系列中,对齐“要求”只是一个字节地址。
        【解决方案5】:

        取决于编译器、编译指示和优化级别。使用现代编译器,您还可以选择时间或空间优化,这也可以改变类型的对齐方式。

        【讨论】:

          【解决方案6】:

          通常是因为这样读取/写入它会更快。但几乎每个编译器都有一个开关来关闭它。在 gcc 中它的 -malign-???。对于聚合,它们通常根据内部每个元素的对齐要求进行对齐和调整大小。

          【讨论】:

            猜你喜欢
            • 2023-03-25
            • 1970-01-01
            • 2019-03-07
            • 2018-03-07
            • 1970-01-01
            • 1970-01-01
            • 2014-01-30
            • 2015-12-15
            • 2019-12-14
            相关资源
            最近更新 更多