C struct padding
我可以在各种编译器上使用pragma pack来强制结构具有不在其自然对齐上的字段。
这是递归的 – 所以假设struct typedef A包含typedef struct B的字段。如果使用pragma打包A将强制结构B打包?
只是不要。 如果不指定您正在使用的确切平台/编译器,您甚至可以提出有关丑陋的非标准扩展的确切行为。 如果您发现自己需要打包结构,那么最好弄明白为什么代码被破坏并修复它。 打包的结构是破坏代码的创可贴,无法解决破坏的根本原因。
你不得不希望! 假设你有一个带参数struct A的函数:
void fn( struct A x ) ;
然后是一个包含struct A作为成员的压缩结构B:
#pragma pack(1) struct B { struct A a ; }
如果将B的成员a传递给fn(),则该函数不知道此实例中的打包,并且会失败。
尽管有其他回答者的结果,我在VC ++ 2010上进行了以下测试:
struct A { int a; char b; int c ; } ; struct B { struct A d ; } ; #pragma pack(1) struct C { struct A d ; } ; #pragma pack(1) struct D { int a; char b; int c ; } ; #pragma pack(1) struct E { struct D ; } ; int main() { int a = sizeof(struct A) ; int b = sizeof(struct B) ; int c = sizeof(struct C) ; int d = sizeof(struct D) ; int e = sizeof(struct E) ; }
检查调试器中main()中的a,b,c,d和e产量:
- a = 12
- b = 12
- c = 12
- d = 9
- e = 9
struct C
的打包对其struct A成员的大小没有影响。
在Nathon的post中,我在电脑上尝试了同样的事情:
#include #if defined PACK_FIRST || defined PACK_BOTH #pragma pack(1) #endif struct inner { char a; double b; }; #if defined PACK_SECOND || defined PACK_BOTH #pragma pack(1) #endif struct outer { char a; struct inner b; char c; double d; }; int main(void) { printf("sizeof (char): %d (1, of course)\n", (int)sizeof (char)); printf("sizeof (double): %d\n", (int)sizeof (double)); printf("sizeof (inner): %d\n", (int)sizeof (struct inner)); printf("sizeof (outer): %d\n", (int)sizeof (struct outer)); return 0; }
$ gcc 4128061.c $ ./a.out sizeof(char):1(当然是1) sizeof(双):8 sizeof(内部):16 sizeof(外部):40 $ gcc -DPACK_FIRST 4128061.c $ ./a.out sizeof(char):1(当然是1) sizeof(双):8 sizeof(内部):9 sizeof(外部):19 $ gcc -DPACK_SECOND 4128061.c $ ./a.out sizeof(char):1(当然是1) sizeof(双):8 sizeof(内部):16 sizeof(外部):26 $ gcc -DPACK_BOTH 4128061.c $ ./a.out sizeof(char):1(当然是1) sizeof(双):8 sizeof(内部):9 sizeof(外部):19
显然我的gcc打包从#pragma
行出现。
对于GCC的版本我很方便,看起来像是:
#include typedef struct { char a; int b; }inner_t; #pragma pack(1) typedef struct { char a; inner_t inner; } outer_t; int main() { outer_t outer; outer.inner.a = 'a'; outer.inner.b = 0xABCDEF01; printf ("outer.inner.a: %c\n", outer.inner.a); return 0; }
而且打破printf的gdb让我…
(gdb) x/5xw &outer 0x7fffffffe4b0: 0xffff61a0 0xcdef01ff 0x000000ab 0x00000000 0x7fffffffe4c0: 0x00000000
inner.b
不是单词对齐的。 因此,在GCC 4.4.5的小端64位机器上,如果外部结构被打包,则打包嵌套结构。 请原谅我的typedef,那些不喜欢它们的人。