jmegaffin
jmegaffin

Reputation: 1172

Packing a struct with a union of structs within it

I'm having an issue with structure packing in C. I want the size of this structure to be 4 bytes with all fields in this order, but it ends up being padded out to 8 bytes. I'm guessing that the problem is happening because dclInput and dclOutput are being aligned to a 4-byte boundary. Is it possible to tell the compiler to not align those structures and just trust that I am not going to ask for a pointer to either one? I have tried using #pragma pack(1) but that didn't help. EDIT: Unfortunately, __attribute__((packed)) doesn't work either - the size still ends up being 8 bytes.

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

Upvotes: 1

Views: 2434

Answers (2)

rohit89
rohit89

Reputation: 5773

Did you put the #pragma pack(1) before your structure or union?

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

I can get the size down to four bytes with this. __attribute__ ((packed)) gave me six bytes.

Upvotes: 0

BadZen
BadZen

Reputation: 4273

It is possible with some compilers, but is not portable C, so you should probably not rely on it.

For example, in gcc, you can use the packed type attribute:

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

Upvotes: 2

Related Questions