声明(十三)
六、对齐说明符
对齐说明符(alignment specifier)具有以下两种语法格式:
alignas ( type-name ) alignas ( constant-expression )
其中type-name是类型名,constant-expression是常量表达式。第一种格式等价于:
alignas(alignof( type-name ) )
(注:ISO/IEC 9899:2024标准中alignas是C语言关键词,可以直接使用;ISO/IEC 9899:2018标准中alignas是<stdalign.h>头文件中定义的宏,使用时需包含<stdalign.h>头文件。)
ISO/IEC 9899:2024标准对对齐说明符的使用作了一些限制:
-- 对齐说明符只能出现在声明的声明说明符中,或者成员声明的说明符限定符列表中,或者复合字面量的类型名中。对齐说明符不能与存储类说明符typedef或者register一起使用,也不能用于函数或者位字段的声明。
typedef alignas(8) int i8; //非法。 struct s{ alignas(8) int i; //合法。 alignas(1) bool b : 1; //非法。 }; alignas(8) int i; //合法。 (alignas(8) int []){3, 5}; //合法。
-- 常量表达式应为整数常量表达式,其值应为有效的基本对齐,或者实现支持的有效扩展对齐(该扩展对齐应适用于声明的存储期限的对象。),或者为0。
每个有效对齐值应是2的非负整数幂。
struct s{ double d; alignas(0) int arr[]; //合法。 };
弹性数组成员不占结构的存储空间;值为0的指定对齐无任何作用。
-- 如果某种过度对齐类型实现不支持,则不可以使用此过度对齐类型声明对象。
-- 声明中所有对齐说明符的综合效果不得指定比声明对象或者成员类型所要求的对齐方式更不严格的对齐方式。
alignas(1) int i; //非法。
声明对象或者成员的对齐要求视为指定对齐方式。当一个声明中出现多个对齐指定时,有效对齐要求是最严格的指定对齐。
alignas(2) alignas(4) short sh4; //sh4的有效对齐值是4。
如果对象定义存在对齐说明符,该对象的其它声明应指定等价对齐或者没有对齐说明符。如果对象定义不存在对齐说明符,该对象的其它声明应不存在对齐说明符。如果同一对象在不同编译单元中声明时具有不同对齐说明符,其行为是未定义的。
static int a; //定义a。 alignas(8) static int b; //定义b。 { extern int a; //声明a,合法。 extern int b; //声明b,合法。 } { alignas(8) extern int a; //声明a,非法。 alignas(8) extern int b; //声明b,合法。 } { alignas(4) extern int b; //声明b,非法。 }