对象对齐
完整对象类型都有对齐要求,给完整对象类型的对象分配地址时会受对齐要求的限制。对齐是实现定义的整数值,表示可以分配给指定对象的连续地址的字节数。对象类型对该类型的每个对象都有对齐要求;可以使用关键词alignas请求更严格的对齐。
(注:alignas是ISO/IEC 9899:2024标准新增的C语言关键词;ISO/IEC 9899:2018标准中alignas是<stdalign.h>头文件中定义的宏。)
int i; printf("%zu\n", alignof(int)); //输出4。 printf("%p\n", &i); //输出0x7ffffcc3c。 alignas(double) float f; //按double类型的对齐要求对齐f。 printf("%zu\n", alignof(float)); //输出4。 printf("%zu\n", alignof(f)); //输出8。
编译环境中int类型对象占4个字节,所以int类型对象的首地址应是4的整数倍。alignas(double) float f;语句要求按double类型的对齐要求对齐float类型对象f。
一、基本对齐
基本对齐(fundamental alignment)是小于或者等于alignof(max_align_t)的有效对齐。实现应支持所有存储期限对象的基本对齐。
(注:alignof是ISO/IEC 9899:2024标准新增的C语言关键词;ISO/IEC 9899:2018标准中alignof是<stdalign.h>头文件中定义的宏。)
以下类型的对齐应为基本对齐:
- 所有原子的、限定的或者非限定的基本类型;
- 所有原子的、限定的或者非限定的枚举类型;
- 所有原子的、限定的或者非限定的指针类型;
- 元素类型具有基本对齐要求的所有数组类型;
- ISO/IEC 9899:2024标准第7 Library章中指定为完整对象类型的所有类型;
- 所有结构类型或者联合类型,其成员类型具有基本对齐要求,且没有成员的对齐说明符指定的对齐不是基本对齐。
二、扩展对齐
扩展对齐(extended alignment)是大于alignof(max_align_t)的对齐表示。是否支持扩展对齐以及支持何种存储期限的扩展对齐将由实现定义。具有扩展对齐要求的类型是过度对齐类型(over-aligned type)。每个过度对齐类型都是或者包含一个结构或者联合类型,其成员已应用扩展对齐。
对齐表示为size_t类型的值。有效对齐仅包括基本对齐以及额外的实现定义值集(这些值可能为空。)。每个有效对齐值应是2的非负整数幂。
对齐具有从弱到强或者更严格的对齐顺序。更严格的对齐具有更大的对齐值。满足更严格对齐要求的地址也满足任何较弱的有效对齐。
可以使用alignof表达式查询完整类型的对齐要求。char、signed char和unsigned char类型应具有最弱的对齐要求。
三、比较对齐
比较对齐:
- 当两个对齐值相等时,两个对齐是相等的。
表达式alignof(signed)和表达式alignof(unsigned)的值相等,signed类型和unsigned类型的对象对齐是相等的。
- 当两个对齐值不相等时,两个对齐是不同的。
表达式alignof(short)和表达式alignof(int)的值不相等,short类型和int类型的对象对齐是不同的。
- 当一个对齐大于另一个对齐时,表示该对齐具有更严格的对齐。
表达式alignof(short)值为2,表达式alignof(int)值为4,int类型对象比short类型对象具有更严格的对齐。
主要参考资料: