字段的__attribute__((packed))如何影响包含该字段的结构体?

eh57zj3b  于 2023-10-16  发布在  其他
关注(0)|答案(1)|浏览(115)

如果我的整个结构中有一个已打包的字段,为什么整个结构都是打包的?
范例:

#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;
}

https://ideone.com/bjoZHB
bar结构体的Sizeof是6,但它应该是12,因为它应该对齐。

n3ipq98p

n3ipq98p1#

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

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

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

struct bar {
  char b;
  __attribute__((packed)) int bla;
  char a;
  int c;
};

大小为12,因为它在4字节边界上对齐c。在你的例子中,如果你同时使用aligned属性,它会像你期望的那样工作:

struct bar {
  char b;
  __attribute__((aligned (4), packed)) int bla;
  char a;
};

该结构尺寸为12。

更新:

我只在GCCattributesaligned 部分找到了这个。我认为这与我在这里提到的有关:

aligned属性只能增加对齐度;但是你也可以通过指定packed来减少它

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

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

struct bar {
  char b;
  __attribute__((aligned(4))) struct foo bla;
  char a;
};

但是如果你在foo的声明中使用aligned()作为__attribute__((aligned (4), packed)),大小将是16。发生这种情况是因为foo也会对齐,并且在打包的情况下它不会有用。

相关问题