C语言 c 结构中的压缩位域 - GCC

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25822679/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 11:22:15  来源:igfitidea点击:

Packed bit fields in c structures - GCC

cgccstructbit-fieldspacked

提问by Danny Cohen

I am working with structs in c on linux. I started using bit fields and the "packed" attribute and I came across a wierd behavior:

我正在 linux 上使用 c 中的结构。我开始使用位字段和“packed”属性,但遇到了一个奇怪的行为:

struct t1
{
    int a:12;
    int b:32;
    int c:4;
}__attribute__((packed));

struct t2
{
    int a:12;
    int b;
    int c:4;
}__attribute__((packed));

void main()
{
    printf("%d\n",sizeof(t1)); //output - 6
    printf("%d\n",sizeof(t2)); //output - 7
}

How come both structures - that are exactly the same - take diffrent number of bytes?

为什么这两种结构 - 完全相同 - 采用不同数量的字节?

回答by Mat

Your structures are not "exactly the same". Your first one has three consecutive bit-fields, the second has one bit-field, an (non bit-field) int, and then a second bit-field.

您的结构并不“完全相同”。你的第一个有三个连续的位域,第二个有一个位域,一个(非位域)int,然后是第二个位域。

This is significant: consecutive (non-zero width) bit-fields are merged into a single memory location, while a bit-field followed by a non-bit-field are distinct memory locations.

这很重要:连续(非零宽度)位字段合并到单个内存位置,而位字段后跟非位字段是不同的内存位置。

Your first structure has a single memory location, your second has three. You can take the address of the bmember in your second struct, not in your first. Accesses to the bmember don't race with accesses the aor cin your second struct, but they do in your first.

你的第一个结构有一个单一的内存位置,你的第二个有三个。您可以b在第二个结构中获取成员的地址,而不是在第一个中。对b成员的访问不会与在您的第二个结构中访问aor竞争c,但它们会在您的第一个结构中进行。

Having a non-bit-field (or a zero-length bit-field) right after a bit-field member "closes" it in a sens, what follow will be a different/independent memory location/object. The compiler cannot "pack" your bmember inside the bit-field like it does in the first struct.

在位域成员以某种方式“关闭”它之后立即具有非位域(或零长度位域),接下来将是不同/独立的内存位置/对象。编译器不能b像在第一个结构中那样将您的成员“打包”在位域中。

回答by John Zwinck

struct t1 // 6 bytes
{
    int a:12; // 0:11
    int b:32; // 12:43
    int c:4;  // 44:47
}__attribute__((packed));

struct t1 // 7 bytes
{
    int a:12; // 0:11
    int b;    // 16:47
    int c:4;  // 48:51
}__attribute__((packed));

The regular int bmust be aligned to a byte boundary. So there is padding before it. If you put cright next to athis padding will no longer be necessary. You should probably do this, as accessing non-byte-aligned integers like int b:32is slow.

正则int b必须与字节边界对齐。所以在它之前有填充。如果你把它放在c旁边,a这个 padding 就不再需要了。您可能应该这样做,因为访问非字节对齐的整数int b:32很慢。