Search code examples
structsizeofunionsbit-fieldsxc16

Why does this typedef give a sizeof() value larger than expected?


I use typedefs of this form to simplify access to microprocessor registers and bit fields within them.

  typedef union
  {
     uint8_t        u8Byte;           ///< REG_8 as unsigned byte
     int8_t         i8Byte;           ///< REG_8 as signed byte
     struct
     {
        unsigned b0:1;                ///< Bit 0 of REG_8 type
        unsigned b1:1;                ///< Bit 1 of REG_8 type
        unsigned b2:1;                ///< Bit 2 of REG_8 type
        unsigned b3:1;                ///< Bit 3 of REG_8 type
        unsigned b4:1;                ///< Bit 4 of REG_8 type
        unsigned b5:1;                ///< Bit 5 of REG_8 type
        unsigned b6:1;                ///< Bit 6 of REG_8 type
        unsigned b7:1;                ///< Bit 7 of REG_8 type
     };
  } REG_8;

Unfortunately, sizeof(REG_8) returns 2 instead of the expected 1. Similar definitions for REG_16 and REG_32 return sizes of 2 and 4, as expected. sizeof(uint8_t) and sizeof(int8_t) return 1, as expected.

The type works as expected. For example,

REG_8  a;
a.u8Byte = 4;

gives a.b2 a value of 1, so there is no alignment issue.

Removing the struct gives a sizeof value of 1, so it looks like there is a padding issue, but if so, why?

Can anyone explain this? I'm using the Microchip XC16 compiler (based on GCC) targeting a 16-bit processor.


Solution

  • Probably sizeof(unsigned)=2 on your machine, so any "unsigned" bit field occupies at least 2 bytes. Replacing unsigned by uint8_t should bring sizeof(REG_8) to 1.

    See also this question: How is the size of a struct with Bit Fields determined/measured?