Bitfields in C with struct containing union of structs

匿名 (未验证) 提交于 2019-12-03 07:50:05

问题:

Hm... why is it that, when I print sizeof(struct MyStruct), it outputs 3 (instead of 2) for this code?

#pragma pack(push, 1)     struct MyStruct     {         unsigned char a : 6;         union         {             struct             {                 unsigned int b : 9;             };         };     }; #pragma pack(pop)

In case it matters, I'm running MinGW GCC 4.5.0 on Windows 7 x64, but honestly, the result is weird enough for me that I don't think the compiler and the OS matter too much here. :\

回答1:

You can't have the field starting at an address that is not byte aligned. You're expecting:

6 bits + 9 bits -> 15 bits -> 2 bytes

but what you're getting is:

6 bits -> 1 byte 9 bits -> 2 bytes total ->  3 bytes

The data is being stored as:

| 1 byte | 2 byte |3 byte |   aaaaaaXX bbbbbbbb bXXXXX  

when you were expecting:

| 1 byte | 2 byte |  aaaaaabb bbbbbbbX  

edit: To clarify based on the comments below:

The union (and the containing struct) must be byte aligned. It doesn't matter that the contents are only 9 bits, the union/struct itself is a full 16 bits. Notice that you cannot do the following:

struct MyStruct {     unsigned char a : 6;     union     {         struct         {             unsigned int b : 9;         } c:9;     } d:9; };

As C won't let you specify the entire struct's bit-size.



回答2:

Adding to the answer given by @nss -- my apologies, this would've been a comment if comments weren't so limited on formatting:

#include <stdlib.h>  struct Test {   unsigned short x : 6;   unsigned short y : 1;   unsigned short z; };  int main( int argc, char *argv[] ) {   printf( "sizeof( Test ) = %d\n", sizeof( struct Test ) );    return 0; }

It prints '4' for the size. I tested with gcc, g++, and Sun Studio's CC and cc.

Not that I recommend doing what you're attempting to do, but you could probably do what you're attempting to do with a union. I've seen (but not written myself) code that looked like this:

struct Test {   unsigned short x1 : 6;   unsigned short x2 : 3;                     : 1; // unused   unsigned short x3 : 4;   // ... };

I might have the syntax slightly wrong there ... but I don't think so.

Point being: create two separate structs (or a struct and a union) with the layout you were going for, then insert some dummy members where they should overlap, and union those together.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!