我使用这种形式的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)。
答案 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;