【问题标题】:Why does this typedef give a sizeof() value larger than expected?为什么这个 typedef 给出的 sizeof() 值比预期的大?
【发布时间】:2015-10-07 21:14:40
【问题描述】:

我使用这种形式的 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,因此不存在对齐问题。

删除 struct 后,sizeof 的值为 1,因此看起来存在填充问题,但如果是,为什么?

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

【问题讨论】:

  • 我的猜测是,由于严格的数据对齐寻址,您的 16 位机器将为您的一字节联合使用 1 字节填充。这是一个猜测,因为我不熟悉机器/编译器。
  • @IanGabes 在这台 16 位机器上,字确实需要在偶数地址上对齐,但是机器可以访问任何地址的字节(即,没有对齐要求)

标签: struct sizeof unions bit-fields xc16


【解决方案1】:

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

另请参阅此问题: How is the size of a struct with Bit Fields determined/measured?

【讨论】:

  • sizeof(unsigned) 为 2,但 :1 限定符不是为结构成员覆盖它吗?此外,如果 b7 成员获得 2 个字节,那么联合不应该增长到 3 个字节(2 + 7/8 向上舍入)吗?
  • 每个结构成员将占用 1 位无符号数。 (我不明白您评论的第二部分 - 您将如何声明 b7?)
  • 如果声明无符号 b7:16,则结构需要两个无符号,因此大小应为 4
  • 我的愚蠢 - 我假设无符号 b7 的 LSB 将代表它的价值。请忽略!
【解决方案2】:

似乎@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;

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 1970-01-01
    • 2015-11-11
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    • 1970-01-01
    相关资源
    最近更新 更多