C++标准 alignas 与 windows 封装指令 (pack pragma) 的区别
C++标准 alignas 与 windows 封装指令 (pack pragma) 的区别
结构体内存对齐受到二方面的影响【共同作用】:
一个方面是语言的对齐规则=》语言的对齐规则
参考 https://blog.csdn.net/weixin_43698578/article/details/104801421 【主要影响因素是成员的对齐大小】【基本类型的对齐大小就是其sizeof大小;复合类型的对齐大小是其每个成员对齐大小的最大值(若成员还是复合类型,则递归应用此规则)】
而C++标准关键字alignas 的语义就是直接指定 复合类型的对齐大小的【仅此而已=>即不会影响复合类型它自己的成员的对齐大小,也不管实际的封包对齐过程(这由封装控制)】=>所以alignas这样干巴巴的直接指定是有限制的那就是不能指定比此复合类型按原生(正常方式)判定的对齐大小更小的值!
另一个方面是封包的影响:
平台编译器在内部会维护一个封包(封装)堆栈;此封包(装)堆栈栈顶的记录项对应的值;就是当前使用的封装对齐值【这是一个新概念】;这个封装对齐值会影响到结构体对齐的过程:具体行为是=>将每个成员的对齐大小与此封装对齐值比较,并选用较小的【注:这里是取用较小的了】;作为对齐过程中影响内存布局的实际对齐值(就暂时称为对齐分布值吧);每个成员在结构体中内存偏移位置必须是其对齐分布值的整数倍;整个结构体对象在内存中的位置,也必须是这个结构体对象的对齐分布值的整数倍!
(每个实体(无论是成员还是对象)的对齐分布值=>
是由 封装对齐值 和 此实体的对齐大小 共同决定【即这二个值比较并选用最小的】
封装对齐值:(编译期由编译器根据编译程序内部维护的封装堆栈栈顶记录项的值为每个类型指定)
【是编译源代码时,在编译过程(对于编译程序是运行期动态的)中编译器内部维护的封装堆栈的栈顶记录项对应的值确定;在编译源码过程中,编译器编译到类型(无论是处理基础类型,还是复合类型)时会将编译期内部维护的封装堆栈的栈顶记录项对应的值指定为此类型的封装对齐值】
而pack pragma 编译指令就是在编译期编译器运行时处理每个类型时,对编译器程序动态维护的封装堆栈进行操作=>修改栈顶记录项,让此时类型的封装对齐值被指定为不同的栈顶记录项的值;当然也可以不用pack 指令,那么编译器编译每个模块时,封装堆栈的栈顶记录项有一个默认的值;编译每个类型时取栈顶记录值标记每个类型的封装对齐值的过程是不变的
实体的对齐大小:(根据语言标准确定的,虽然也是编译器编译期确定的)
【粒度是针对每个实体有自己的对齐大小】