对齐的重要性主要体现在性能和可移植性上。如果您不了解您正在使用的平台的对齐要求,您的代码可能不一定能够在那里运行,或者一旦有人移动未正确对齐到该平台的代码(或数据),它就会中断。
根据硬件和操作系统等因素,其中一些会为您处理,但您会因制动对齐规则而受到一些惩罚。默认情况下,旧的 Windows 版本在发生对齐错误时会导致进程崩溃,今天 Windows 将能够恢复,但代价是额外的 CPU 周期。
对齐属性是强制对齐的 GCC 特定功能(它与 C 语言无关),对齐是您的数据必须在内存中布置的某个数字的倍数。然后,编译器将在您的数据结构中插入垃圾,以确保满足您对编译器施加的约束。
让我们以您的问题为例:
struct data
{
int a __attribute__( ( aligned ( 8 ) ) ) ;
char ch __attribute__( ( aligned ( 1 ) ) ) ;
float s __attribute__( ( aligned ( 4 ) ) ) ;
} ;
我们假设在这种情况下int
,float
我们假想平台上的原生大小都是 4 字节。
在内存中布局的最终结构将更接近
struct data
{
int a; // 0x00
int junk0 // 0x04
char ch; // 0x08
char junk1[3] // 0x09
float s; // 0x0C
} ;
我不确定编译器是否会填充第一个整数,以便它在最终结构中实际占用 8 个字节。仅仅因为填充,它不会是 64 位的,我觉得很奇怪,因为它会假设结构仅放置在 64 位地址上,所以在 32 位架构中,如果你分配内存,只有当内存对齐在一个 8 的倍数的地址是可以的。也许这是为了让它更便携,以确保它在 32 位和 64 位上的行为相同。
编译器可以选择更激进,实际上浪费更多空间,但是有包指令可以解决这个问题。如果本机二进制兼容性对您来说真的很重要,那么这些事情真的很重要。