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

标签 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;
}

https://ideone.com/bjoZHB

bar 结构的 Sizeof 是 6,但它应该是 12,因为它应该对齐。

最佳答案

似乎是因为__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 部分找到了这个.我认为这与我在这里提到的有关:

The aligned attribute can only increase the alignment; but you can decrease it by specifying packed as well

。请记住,如果您想要保持子结构紧凑但主结构对齐,您需要在 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 也对齐了,并且在打包的情况下没有用。

关于c - 字段的 __attribute__((packed)) 如何影响包含该字段的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54010839/

相关文章:

c++ - 使用 C++ 方式对结构和数组进行别名处理

c - C 中类似函数的宏定义

c - 在 Linux 中从/proc 文件系统获取硬件信息

c++ - AddressSanitizer GCC 4.8 双重释放错误

c++ - 结束字符 `\0`算一个字符还是两个字符?

typedef (timer_t) 的冲突类型错误

c++ - gcc3 和 gcc4 关于未初始化变量的区别

c - 父级向子级发送命令行参数

c++ - ASCII码打印逻辑

C 内存集输出