C中的位域,结构包含结构的并集

时间:2011-02-20 03:52:03

标签: c struct unions bit-fields

嗯...为什么当我打印sizeof(struct MyStruct)时,它为此代码输出3(而不是2)?

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

如果重要的话,我在Windows 7 x64上运行MinGW GCC 4.5.0,但老实说,结果对我来说很奇怪,我不认为编译器和操作系统在这里太重要了。 :\

2 个答案:

答案 0 :(得分:13)

您不能让字段从非字节对齐的地址开始。 你期待的是:

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

但你得到的是:

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

数据存储为:

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

当你期待的时候:

| 1 byte | 2 byte |
 aaaaaabb bbbbbbbX  

编辑: 根据以下评论澄清:

union(和包含结构)必须是字节对齐的。内容只有9位并不重要,union / struct本身是一个完整的16位。请注意,您无法执行以下操作:

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

由于C不允许您指定整个结构的位大小。

答案 1 :(得分:0)

添加@nss给出的答案 - 我的道歉,如果评论的格式不是那么有限,这将是一个评论:

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

打印尺寸为'4'。我测试了gcc,g ++和Sun Studio的CC和cc。

不是我建议你做你想做的事情,但你可能会做你正试图用联盟做的事情。我见过(但不是自己写的)代码看起来像这样:

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

我的语法可能略有错误......但我不这么认为。

要点:使用你想要的布局创建两个单独的结构(或结构和联合),然后插入一些它们应该重叠的虚拟成员,并将它们组合在一起。