为什么此 typedef 给出的 sizeof() 值大于预期?
Why does this typedef give a sizeof() value larger than expected?
我使用这种形式的 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)
returns 2 而不是预期的 1。类似定义 REG_16 和 REG_32 return 大小 2 和 4,正如预期的那样。 sizeof(uint8_t)
和 sizeof(int8_t)
return 1,符合预期。
该类型按预期工作。例如,
REG_8 a;
a.u8Byte = 4;
给a.b2
一个值1,所以不存在对齐问题。
删除 struct
得到 sizeof
值 1,因此看起来存在填充问题,但如果是这样,为什么呢?
谁能解释一下?我正在使用针对 16 位处理器的 Microchip XC16 编译器(基于 GCC)。
可能在您的机器上 sizeof(unsigned)=2,所以任何 "unsigned" 位字段至少占用 2 个字节。用 uint8_t 替换无符号应该使 sizeof(REG_8) 为 1.
另见这个问题:
How is the size of a struct with Bit Fields determined/measured?
看来@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;
我使用这种形式的 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)
returns 2 而不是预期的 1。类似定义 REG_16 和 REG_32 return 大小 2 和 4,正如预期的那样。 sizeof(uint8_t)
和 sizeof(int8_t)
return 1,符合预期。
该类型按预期工作。例如,
REG_8 a;
a.u8Byte = 4;
给a.b2
一个值1,所以不存在对齐问题。
删除 struct
得到 sizeof
值 1,因此看起来存在填充问题,但如果是这样,为什么呢?
谁能解释一下?我正在使用针对 16 位处理器的 Microchip XC16 编译器(基于 GCC)。
可能在您的机器上 sizeof(unsigned)=2,所以任何 "unsigned" 位字段至少占用 2 个字节。用 uint8_t 替换无符号应该使 sizeof(REG_8) 为 1.
另见这个问题: How is the size of a struct with Bit Fields determined/measured?
看来@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;