3

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

更多信息:

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

字符富[5]

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

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

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

4

6 回答 6

10

正如其他人所提到的,这不是标准的一部分,而是留给编译器来实现,因为它认为适合所讨论的处理器。例如,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)的未对齐访问。

于 2008-09-18T15:50:56.647 回答
3

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

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

于 2008-09-18T15:31:11.390 回答
1

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

于 2008-09-18T16:26:47.293 回答
0

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

不然怎么可能?

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

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

#define ALIGNMENT_OF( t ) offsetof( struct { char x; t test; }, test )
于 2008-09-18T15:28:38.167 回答
0

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

于 2008-09-18T15:34:17.123 回答
0

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

于 2008-09-18T15:37:43.027 回答