|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
默认情况下,在32位cpu里,gcc对于结构体的对齐方式是按照四个字节来对齐的。看以下结构体 # f) C! x* {4 ~! V2 x; A
typedef struct pack{
7 T, l$ J* h# `+ j6 I/ y char a;
6 `" u z9 n$ }4 [0 \, I int b;
2 J' ~2 y2 m' r1 ] short c; y. r% f6 x I+ E7 w2 u' B+ V- F
}pack;
2 q* i" n0 b1 J1 f. E- H: d6 \0 a 对于Pack结构体,默认情况下在ARM/386平台下(别的平台没试过)sizeof(pack)=12,求解过程如下: - W# `) W% ~4 Y% O- c) Z
sizeof(char)=1; 0 }- M+ V# z, X. A t7 v
下一个int b,由于是四个字节,要求b的开始地址从32的整数倍开始,故需要在a后面填充3个没用的字节,记为dump(3),sizeof(b)=4,此时相当于结构体扩充为
. l& E' m6 Y h* j$ s# q char a; $ ]! E! Y9 @, g4 w
char dump(3); ' G$ J/ N# s5 T/ G6 b5 Z& b
int b;
) E2 R! H8 [2 H; Z9 Z 看short c,现在c的前面有8个字节,c是两个字节,c的开始地址是从16的整数开始,在b前面不需再加东西.此时对于结构体来说,sizeof(pack)=10,但是这不是最终结果,最后总的字节数也要能被4个字节整除,所以还需在short c后面再加
3 [8 t- ?, ]5 ~6 ?. a( N dump(2);
7 ~: Q' w0 g* q1 k1 M 故总的字节数为12. 0 A* a) R$ v" b' s% u1 A
当然以上说的只是简单的情况,下面谈谈arm,x86在gcc里关于内存边界字节对齐的区别.对于同样的结构体,在386下
/ N4 r7 _0 q9 [ #prama pack(1)
+ ^! R3 J% U D7 w 后,sizeof(pack)=1 4 2=7
& W" Z' |, c$ n5 `1 C 而在arm下同样的操作sizeof(pack)=1 4 2 1=8,即虽然b根a之间不要填充但总的长度必须要是4的整数倍. : Y* p5 y* i7 e$ T
在arm 下要使结构体按指定字节对齐,可行的方法
7 @7 g9 }: a1 _ 1.在makefile里加-fpack-struct 选项,这样的话对所有的结构按一字节对齐. ) n+ `5 e) D2 N4 v3 ?, R$ b
不得不说,确实有那么些质量较差的程序可能需要你部分自然对齐,部分一字 节对齐,此时
+ t# r6 J5 X+ e+ c5 v: x. N 2. typedef struct pack{ , U2 n2 j+ O4 A7 B4 D
}__attribute__((packed))
# v0 w: @2 g. @ Z# ^ 可利用__attribute__属性
" \( d0 a: L% K# F1 O. I1 T 当然最后的方式,还是自己去看arm体系结构与gcc编译选项了。
/ {, M1 j% E3 {) w0 z! u |
|