POD类型是否始终对齐?

时间:2008-09-18 15:27:16

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

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

更多信息:

一个。可以明确地创建一个未对齐的整数(* bar):

  

char foo [5]

     

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

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

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

6 个答案:

答案 0 :(得分:9)

正如其他人所提到的,这不是标准的一部分,而是由编译器实现,因为它认为适合所讨论的处理器。例如,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处理器会抛出一个处理器异常,该异常将被操作系统捕获。然后,OS将检查指令,然后执行处理未对齐数据所需的工作。然后执行继续。可以在VC中使用__unaligned关键字来标记非x86程序的未对齐访问(即CE)。

答案 1 :(得分:3)

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

进行更改

我不相信C ++标准在这方面提出任何要求,并将其付诸实施。

答案 2 :(得分:1)

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

答案 3 :(得分:0)

是的,所有类型始终至少与其对齐要求保持一致。

怎么会这样呢?

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

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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