为什么这个typedef给出的sizeof()值大于预期值?

时间:2015-10-07 21:14:41

标签: struct sizeof unions bit-fields xc16

我使用这种形式的typedef来简化对微处理器寄存器及其中位域的访问。

DetailView

不幸的是, 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; 返回2而不是预期的1. REG_16和REG_32的类似定义返回大小为2和4,如预期的那样。正如预期的那样sizeof(REG_8)sizeof(uint8_t)返回1.

该类型按预期工作。例如,

sizeof(int8_t)

赋予REG_8 a; a.u8Byte = 4; 一个值1,因此没有对齐问题。

删除a.b2会将struct的值设为1,因此看起来有填充问题,但如果有,为什么?

任何人都能解释一下吗?我使用针对16位处理器的Microchip XC16编译器(基于GCC)。

2 个答案:

答案 0 :(得分:2)

你机器上的sizeof(unsigned)= 2,所以任何&#34; unsigned&#34;位字段占用至少2个字节。用uint8_t替换unsigned将使sizeof(REG_8)变为1。

另见这个问题: How is the size of a struct with Bit Fields determined/measured?

答案 1 :(得分:0)

似乎@twin有正确的想法,虽然我也找到了另一个解决方案。给出预期sizeof(REG_8) == 1的两个替代方案是:

  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
     } __attribute__((packed));
  } REG_8;

...或...

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