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.
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?