__attribute __((packed))如何影响包含该字段的struct?

Suk*_*lay 7 c gcc

如果我的结构中有一个字段,那么为什么我的整个结构都会被打包?

例:

#include <stdio.h>

struct foo {
  int a;
} __attribute__((packed));

struct bar {
  char b;
  struct foo bla;
  char a;
};

int main() {
  printf("%ld\n", sizeof(struct bar));
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

https://ideone.com/bjoZHB

barstruct的sizeof 是6,但它应该是12,因为它应该是对齐的.

Afs*_*hin 6

似乎因为__attribute__((packed))意味着对结构使用最小内存,这也意味着当它在另一个结构中时它可以忽略对壁板成员的对齐.检查以下结构:

struct bar {
  char b;
  __attribute__((packed)) int bla;
  char a;
};
Run Code Online (Sandbox Code Playgroud)

当你检查这个结构的大小时,它将是6.这是因为它忽略了2个成员(ab这里)的成员对齐.但这个结构:

struct bar {
  char b;
  __attribute__((packed)) int bla;
  char a;
  int c;
};
Run Code Online (Sandbox Code Playgroud)

大小为12,因为它c在4个字节边界上对齐.在您的情况下,如果您同时使用aligned属性,它可以按预期工作:

struct bar {
  char b;
  __attribute__((aligned (4), packed)) int bla;
  char a;
};
Run Code Online (Sandbox Code Playgroud)

这个结构大小是12.

更新:

我只在属性GCC对齐部分找到了这个.我认为这与我在这里提到的有关:

所述对准属性只能增加对准; 但可以通过指定减少其包装以及

请记住,如果要保持子结构包装但主结构对齐,则需要在2个不同的声明中使用2个属性.例如,以下结构的大小为12:

struct foo {
  char b;
  int a;
} __attribute__((packed));

struct bar {
  char b;
  __attribute__((aligned(4))) struct foo bla;
  char a;
};
Run Code Online (Sandbox Code Playgroud)

但如果你aligned()fooas的声明中使用__attribute__((aligned (4), packed)),则大小将为16.这是因为foo得到了对齐,并且在打包的情况下它不会有用.