sizeof 和 alignment(对齐)
1: alignment的定义 alignment指的是对象的开始地址必须满足条件: >>#pragma pack(push, 1) <<任何地址
>>#pragma pack(push, 2) <<偶数地址
>>#pragma pack(push, 4) <<地址必须是4的倍数
>>#pragma pack(push, 8) <<地址必须是8的倍数
2: 基本类型T的alignment(T) 对齐值就是上面所说的1, 2, 4, 8
现在对应于每个类型T, 都有一个alignment(T)和T对应, 这个对应关系究竟如何呢:
(以下针对我们现在所碰到的编译器而言) << char --> 1 (永远是1)
<< short #pragma pack(1) --> 1 #pragma pack(2) --> 2 #pragma pack(4) --> 2 // 呵呵,这里是关键 ... --> 2
<< int #pragma pack(1) --> 1 #pragma pack(2) --> 2 #pragma pack(4) --> 4 // 呵呵,这里是关键 ... --> 4 ... 这里就有了一个概念, 我们尚且将其命名为 internal_PACK(T): internal_PACK(char) = 1 internal_PACK(short) = 2 internal_PACK(int) =4 internal_PACK(int64) = 8 ... 和当前编译器的对齐方式无关。
编译其当前设置的#pragma pack(n)值我们命名为 PACK (= n)
那我们就有公式: if (internal_PACK(T) < PACK) alignment(T, PACK) = internal_PACK(T) else alignment(T, PACK) = PACK
下面的这个对任何类型T都成立: alignment(T) <= PACK --------------------------------#1
3 struct(or class)类型ST的alignment(ST)
alignment(ST) = max { alignment(T) | T 是ST的data member 的类型 }
4 举例 << #pragma pack(1) struct A { .... }; 由#1, 在pack(1)的情况下所有的 alignment(type)≡1
<< #pragma pack(4) struct A { char ch; short sh; }; alignment(ch) = 1 alignment(sh) = 2 alignment(A) = 2
<< #pragma pack(8) struct A { char ch; int n; char ch; }; alignment(n) = 4 alignment(A) = 4
<< #pragma pack(2) struct A { char ch; int n; char ch; }; alignment(n) = 2 alignment(A) = 2
5: sizeof(T) << 对基本类型来说 sizeof(T) = internal_PACK(T) << 对结构类型ST来说 把最后一个数据成员m_last去掉后形成的结构叫ST~ sizeof(ST) = sizeof(ST~) + last_size + patch 其中 << last_size = member_patch + sizeof(m_last) member_patch = [sizeof(ST~) 到 比它的alignment(m_last)倍数的最小距离] ; << patch = [sizeof(ST~) + last_size到比它大的alignment(ST)倍数的最小距离]
其中 << member_patch是因为m_last要地址对齐alignment(m_last) << patch 是因为如果声明一个数组的话: ST st[2]; 为了满足 1: st[1] 地址alignment(ST)对齐 2: sizeof(st) = sizeof(st1) + sizeof(st2) 关键是第二条 所以需要patch把余下的空间补满。 
|