【问题标题】:Packing a struct with a union of structs within it将结构与其中的结构联合打包
【发布时间】:2015-07-31 18:00:10
【问题描述】:

我遇到了 C 中的结构打包问题。我希望此结构的大小为 4 个字节,所有字段都按此顺序排列,但最终被填充为 8 个字节。我猜这个问题正在发生,因为 dclInputdclOutput 正在与 4 字节边界对齐。是否有可能告诉编译器不要对齐这些结构并相信我不会要求指向任何一个的指针?我曾尝试使用#pragma pack(1),但这并没有帮助。编辑:不幸的是,__attribute__((packed)) 也不起作用 - 大小仍然是 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;
    };
};

【问题讨论】:

  • 您使用的是哪个编译器?对于 GCC,它应该是 __attribute__ ((__packed__))

标签: c struct alignment unions


【解决方案1】:

在某些编译器上是可能的,但不是可移植的 C,所以你可能不应该依赖它。

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

struct _IL_OPCODE {
    unsigned code : 16;
    union {
        struct {
  ...
    } __attribute__ ((packed))

【讨论】:

    【解决方案2】:

    您是否将#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;
      };
    };
    

    我可以用这个将大小缩小到四个字节。 __attribute__ ((packed)) 给了我六个字节。

    【讨论】:

    • #pragma pack(1) 是 Visual C 的方式,__attribute__((packed)) 是 gcc 的方式。我相信,两个编译器都会忽略“其他”方式。其他编译器我的做法不同。因此“不可移植”。
    • 我不知道 Visual C 忽略 'gcc' 方式,但 gcc 确实支持 #pragma pack。有关信息,请参阅gcc.gnu.org/onlinedocs/gcc/Structure-Packing-Pragmas.html
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多