C 使用结构的并集打包结构

C 使用结构的并集打包结构,c,struct,alignment,unions,C,Struct,Alignment,Unions,我对C中的结构打包有一个问题。我希望此结构的大小为4字节,所有字段都按此顺序排列,但最终填充为8字节。我猜出现问题是因为dclInput和dclOutput与4字节边界对齐。有没有可能告诉编译器不要对齐这些结构,只需相信我不会要求任何一个结构的指针?我尝试过使用#pragma pack(1),但没有效果。编辑:不幸的是,\uuuuuuuuuuuu属性((打包))也不起作用-大小仍然是8字节 struct _IL_OPCODE { unsigned code : 16; union

我对C中的结构打包有一个问题。我希望此结构的大小为4字节,所有字段都按此顺序排列,但最终填充为8字节。我猜出现问题是因为
dclInput
dclOutput
与4字节边界对齐。有没有可能告诉编译器不要对齐这些结构,只需相信我不会要求任何一个结构的指针?我尝试过使用
#pragma pack(1)
,但没有效果。编辑:不幸的是,
\uuuuuuuuuuuu属性((打包))
也不起作用-大小仍然是8字节

struct _IL_OPCODE {
    unsigned code : 16;
    union {
        struct {
            unsigned usage    : 5;
            unsigned mode     : 3;
            unsigned          : 1;
            unsigned bias     : 1;
            unsigned invert   : 1;
            unsigned centered : 1;
            unsigned          : 4;
        } dclInput;
        struct {
            unsigned id          : 8;
            unsigned type        : 4;
            unsigned             : 3;
            unsigned unnormalize : 1;
        } dclResource;
    };
};

在某些编译器中,这是可能的,但它不是可移植的C,所以您可能不应该依赖它

例如,在gcc中,可以使用
packed
type属性:

struct _IL_OPCODE {
    unsigned code : 16;
    union {
        struct {
  ...
    } __attribute__ ((packed))
您是否将
#pragma pack(1)
放在结构或联合之前

#pragma pack(1)          // Put it here OR
struct _IL_OPCODE {
  unsigned code : 16;
  #pragma pack(1)        // here
  union {
    struct {
      unsigned usage    : 5;
      unsigned mode     : 3;
      unsigned          : 1;
      unsigned bias     : 1;
      unsigned invert   : 1;
      unsigned centered : 1;
      unsigned          : 4;
    } dclInput;
    struct {
      unsigned id          : 8;
      unsigned type        : 4;
      unsigned             : 3;
      unsigned unnormalize : 1;
    } dclResource;
  };
};

我可以用这个把大小减少到四个字节<代码>\uuuu属性\uuuu((打包))给了我六个字节。

您使用的是哪种编译器?对于GCC来说,它应该是
\uuuu attribute\uuuuuuuuuuu((\ uuuuu packed\uuuuuuuuuuu))
\pragma pack(1)
是VisualC实现这一点的方法,
\uuuuuu attribute\uuuuuuuuuuuuuuuuuu((packed))
是GCC的方法。我相信,两个编译器都会忽略“另一种”方式。我的其他编译器则不同。因此“不可移植”。我不知道Visual C是否会忽略“gcc”方式,但gcc确实支持
#pragma pack
。有关信息,请参阅。