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,那些不喜欢它们的人。