我有一个这样的结构体:
typedef struct
{
uint8 nibble_1 : 4;
uint8 nibble_2 : 4;
uint8 data_1;
uint8 data_2;
uint8 data_3;
} NibbleStruct;
字符串
这是一个用于CAN通信的32位消息。
在代码中,我有以下内容:
...
NibbleStruct nibble_struct;
uint8 nibble_to_assign = 0U;
nibble_struct.nibble_1 = nibble_to_assign;
...
型
我需要保留GCC(gnu 99)标志-Werror=conversion
,但这给出了错误消息:
file_name.c错误:从“uint 8”转换为“unsigned char:4”可能会改变其值[-Werror=conversion]|
我试着用一些
...
nibble_struct.nibble_1 = (uint8:4) nibble_to_assign;
...
型
和
...
nibble_struct.nibble_1 = (uint8) nibble_to_assign : 4;
...
型
但并不奇怪,这并不编译。
有没有办法将变量nibble_to_assign
转换为结构体的半字节nibble_1
?或者在结构体外部的代码中声明一个半字节。
1条答案
按热度按时间c0vxltue1#
建议将“车库标准”
uint8
删除为ISO C标准uint8_t
。这里有几件事要记住:
uint8_t
的位字段-这是一个不可移植的编译器扩展。-Wconversion
是一个不稳定的编译器选项,容易出现误报和误导性诊断。它很适合用于压力测试/代码审查,但不应该包含在正常构建中。在这种情况下,
-Wconversion
抱怨的问题是,显然不能预测uint8_t
值是否适合4位的位字段。我可以通过强制将未签名的升级到
unsigned int
来关闭它:字符串
但是请注意,无论是结构体还是位字段都不是特别适合或推荐用于建模硬件或数据协议。结构体内部可能有填充字节或填充位。如果你坚持使用结构体,你可能必须编写序列化/非序列化例程来避免填充问题。你可能必须这样做来处理endianess,因为CAN通常(但不总是)使用大端。