3

嗯...为什么,当我 print 时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,但老实说,结果对我来说已经够奇怪了,我认为编译器和操作系统在这里并不重要。:\

4

2 回答 2

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  

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

联合(和包含的结构)必须是字节对齐的。内容只有 9 位没关系,联合/结构本身就是一个完整的 16 位。请注意,您不能执行以下操作:

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

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

于 2011-02-20T03:59:02.527 回答
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;
  // ...
};

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

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

于 2011-08-26T18:33:08.450 回答