《C 编程语言》一书在第 8.7 节 示例 — 存储分配器中讨论了"最严格的类型":
尽管机器各不相同,但对于每台机器来说,都有一个最严格的限制 类型:如果限制性最强的类型可以存储在特定的 地址,所有其他类型也可能是。在某些计算机上,最 限制型是
double
;在其他情况下,int
或long
就足够了。
在他们的代码中,union
header
使用类型 long
对齐。
最严格的类型是什么意思?它可能是最大的类型(例如,double
),还是有另一种方法?
通常需要(或者如果)某些类型的数据存储在某个(2的幂)值的倍数的地址上,则工作效率更高。此值称为数据的对齐方式。例如,CPU 可能要求将四字节整数存储在四的倍数的地址(它们具有四字节对齐方式,或在四个字节上对齐)。
最严格的类型是指在此领域具有最严格要求的类型。因此,如果例如 long double
在某些计算机上需要八字节对齐,并且没有其他类型需要比这更大的对齐,那么该计算机上最严格的类型将是 long double
。
对于malloc(3)
来说,返回满足最严格类型的对齐要求的地址是有意义的,因为这意味着返回的内存可用于存储任何类型的地址。 malloc()
不知道内存将如何使用,因此无法适应。
数据类型需要更大的对齐方式,尽管对齐要求往往会随着大小的增加而增加。
(某些类型的数据可能需要比malloc()
提供的更大的对齐方式。例如,许多 x86 SSE 指令使用在 16 个字节上对齐的数据向量,而例如 glibc 中的malloc()
只保证 8 字节对齐。 posix_memalign(3)
可用于动态分配内存,在 POSIX (*nix) 系统上具有更高的对齐要求。
限制性最强的类型由 max_align_t
定义,在 stddef.h
中定义。根据标准:
基本对齐由小于或的对齐表示 等于实现支持的最大对齐方式 上下文,等于
_Alignof (max_align_t)
.
因此,max_align_t
的对齐方式至少与每种标量类型的对齐方式一样大,并且在大多数实现中,其对齐方式将等于最大的标量类型 - 但标准并不要求这种相等。
该标准进一步要求(强调我的):
通过连续调用分配的存储的顺序和连续性
aligned_alloc
、calloc
、malloc
和realloc
函数为 未指定。如果分配成功,则返回的指针为 适当对齐,以便可以将其分配给指向任何类型的指针 具有基本对齐要求的对象,然后用于 访问空间中的此类对象或此类对象的数组 已分配(直到空间被显式解除分配)。
因此,分配函数返回的任何指针的对齐方式至少与max_align_t
对齐方式一样严格。
我认为引号意味着最严格的类型对齐。例如,如果遵循此逻辑,char 是结构最少的类型。char 类型的对象不会对其对齐方式施加约束,而例如 int 类型的对象通常具有 4 字节边界的对齐要求。因此,int 是比 char 更严格的类型。