0

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

  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;

不幸的是,sizeof(REG_8)返回 2 而不是预期的 1。 REG_16 和 REG_32 的类似定义返回大小为 2 和 4,正如预期的那样。sizeof(uint8_t)并按sizeof(int8_t)预期返回 1。

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

REG_8  a;
a.u8Byte = 4;

给出a.b2值 1,因此不存在对齐问题。

删除1structsizeof值,所以看起来存在填充问题,但如果是这样,为什么?

谁能解释一下?我正在使用针对 16 位处理器的 Microchip XC16 编译器(基于 GCC)。

4

2 回答 2

2

可能 sizeof(unsigned)=2 在您的机器上,因此任何“无符号”位字段至少占用 2 个字节。用 uint8_t 替换 unsigned 应该会使 sizeof(REG_8) 为 1。

另请参阅此问题: 如何确定/测量具有位字段的结构的大小?

于 2015-10-07T21:27:36.257 回答
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;
于 2015-10-07T21:41:02.090 回答