给定数据类型的字节对齐要求是否保证为 2 的幂?
除了“没有意义”之外,还有什么东西可以提供这种保证,因为它与系统页面大小不符?
(背景:C/C++,所以随意假设数据类型是 C 或 C++ 类型并给出 C/C++ 特定的答案。)
给定数据类型的字节对齐要求是否保证为 2 的幂?
除了“没有意义”之外,还有什么东西可以提供这种保证,因为它与系统页面大小不符?
(背景:C/C++,所以随意假设数据类型是 C 或 C++ 类型并给出 C/C++ 特定的答案。)
对齐要求基于硬件。大多数(如果不是全部)“现代”芯片的地址可以被 8 整除,而不仅仅是 2 的幂。过去有不可被 8 整除的芯片(我知道 36 位架构)。
根据 C 标准,您可以假设对齐的事情:
sizeof
)。char
,signed char
和unsigned char
没有对齐要求。(这实际上只是第一点的一个特例。)在现代现实世界中,整数和指针类型的大小是 2 的幂,并且它们的对齐要求通常等于它们的大小(唯一的例外是long long
在 32 位机器上)。浮点数不太统一。在 32 位机器上,所有浮点类型的对齐通常为 4,而在 64 位机器上,浮点类型的对齐要求通常等于类型的大小(4、8 或 16)。
a 的对齐要求struct
应该是其成员对齐要求的最小公倍数,但允许编译器强制执行更严格的对齐。但是,通常每个 cpu 架构都有一个包含对齐规则的 ABI 标准,不遵守该标准的编译器将生成无法与遵循 ABI 标准的编译器构建的代码链接的代码,因此对于除了非常特殊的用途外,编译器要打破标准。
顺便说一句,适用于任何健全的编译器的有用宏是:
#define alignof(T) ((char *)&((struct { char x; T t; } *)0)->t - (char *)0)
简而言之,没有。这取决于硬件。
然而,大多数现代 CPU 要么进行字节对齐(例如,Intel x86 CPU),要么进行字对齐(例如,Motorola、IBM/390、RISC 等)。
即使使用单词对齐,它也可能很复杂。例如,16 位字在 2 字节(偶数)地址上对齐,32 位字在 4 字节边界上对齐,但 64 位值可能只需要 4 字节对齐而不是 8 -字节对齐地址。
对于字节对齐的 CPU,它也是编译器选项的一个功能。通常可以指定结构成员的默认对齐方式(通常也可以使用特定于编译器的#pragma)。
对于基本数据类型(整数、浮点数、双打) 通常对齐匹配类型的大小。对于类/结构,对齐至少是其所有成员对齐的最小公倍数(这是标准)
在 Visual Studio 中,您可以为类型设置自己的对齐方式,但它必须是 2 的幂,介于 1 和 8192 之间。
在 GCC 中有类似的机制,但它没有这样的要求(至少在理论上)
“结构”内的字段对齐,针对大小进行了优化,很可能位于奇数边界上。除此之外,您的“这没有意义”可能会适用,但我认为不能保证,特别是如果程序是小型模型,并针对大小进行了优化。- 乔
该标准不需要对齐,但允许结构/联合/位字段静默添加填充字节以获得正确的对齐。如果需要,编译器还可以自由地将所有数据类型对齐到偶数地址。
话虽如此,这取决于 CPU,而且我不相信存在对奇数地址有对齐要求的 CPU。然而,有很多没有对齐要求的 CPU,然后编译器可以将变量放在任何地址。