字段的 __attribute__((packed)) 如何影响包含该字段的结构?
Posted
技术标签:
【中文标题】字段的 __attribute__((packed)) 如何影响包含该字段的结构?【英文标题】:How does __attribute__((packed)) for a field affect struct which contains this field? 【发布时间】:2019-01-02 17:44:08 【问题描述】:如果我的结构中有一个已打包的字段,为什么我的整个结构都被打包了?
例子:
#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
struct 的 Sizeof 是 6,但应该是 12,因为它应该是对齐的。
【问题讨论】:
【参考方案1】:似乎是因为__attribute__((packed))
意味着对结构使用最小内存,这也意味着当它在另一个结构中时它可以忽略侧板成员的对齐。检查以下结构:
struct bar
char b;
__attribute__((packed)) int bla;
char a;
;
当您检查此结构的大小时,它将是 6。发生这种情况是因为它忽略了 2 个侧面成员的成员对齐(@987654324@ 和 b
此处)。但是这个结构:
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。
更新:
我只在 attributes 的 GCC
的 aligned 部分找到了这个。我认为这与我在这里提到的有关:
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
也对齐了,在打包的情况下它不会有用。
【讨论】:
我在哪里可以读到“意味着当它在另一个结构中时它可以忽略对齐”我在 gcc 文档或任何地方都没有找到它。 :( @SukhanovNiсkolay 它在句子的开头也有一个“似乎”。但我在 gcc 手册中找到了 1 句话,我将其添加到回复中。 是的,我看到了同样的引用,那么它似乎是 ISO C 的要求。 :) 更新:抱歉,引用错误,我看到了:“ISO C 标准至少是结构所有成员对齐的最低公倍数的完美倍数”以上是关于字段的 __attribute__((packed)) 如何影响包含该字段的结构?的主要内容,如果未能解决你的问题,请参考以下文章
GCC 的 __attribute__((__packed__)) 是不是保留原始顺序?
如果我将字节数组转换为 __attribute__((packed, aligned(2))) 结构会发生啥?
高级C__attribute__((aligned(n))) 与 #pragma(pack(n))的区别