我有一个用位字段表示29位CAN标识符的结构,如下所示。
struct canId
{
u8 priority :3;
u8 reserved :1;
u8 dataPage :1;
u8 pduFormat :8;
u8 pduSpecific :8;
u8 sourceAddress :8;
} iD;在我的代码中,我想把这个结构复制到一个整型变量中。类似于:
int newId = iD; 然而,我不确定这是否正确。有人能对此发表评论吗?
编辑:我可以在每个字段上使用移位运算符,然后使用逐位OR来将它们放在正确的位置。但这使得使用带有位字段的结构在一开始就无用了。
发布于 2016-04-22 22:01:55
对于真正可移植的解决方案,您根本不应该使用位字段的结构,因为字段布局是未定义的。取而代之的是使用整数和显式按位运算。
但是对于更轻松的解决方案,int和bitfield结构的结合就足够好了。
为了既安全又方便,您还可以考虑集成一个测试函数,该函数一次切换一个字段,并检查与所需整数的匹配情况。
union
{
uint32_t packed;
struct canId
{
u8 priority :3;
u8 reserved :1;
u8 dataPage :1;
u8 pduFormat :8;
u8 pduSpecific :8;
u8 sourceAddress :8;
} split;
} iD;
iD.packed= 0; iD.split.priority= 7; if (iD.packed != 0x7) ...发布于 2016-04-22 21:16:00
我希望我的小魔法没弄错。您可能会这样做:
newID = (int)iD.priority
| (int)(iD.reserved) << 3
| (int)(iD.dataPage) << (3 + 1)
| (int)(iD.pduFormat) << (3 + 1 + 1)
| (int)(iD.pduSpecific) << (3 + 1 + 1 + 8)
| (int)(iD.sourceAddress) << (3 + 1 + 1 + 8 + 8)但要做到这一点,您需要一个int至少有32位的系统
发布于 2016-04-22 21:19:14
抛开位字段的顺序是由实现定义的问题不谈,您总是可以填充位字段,使其成为32位,然后将其memcpy到int中
struct canId
{
u8 priority :3;
u8 reserved :1;
u8 dataPage :1;
u8 pduFormat :8;
u8 pduSpecific :8;
u8 sourceAddress :8;
u8 _padding :3;
} iD;
int newId = 0;
static_assert(sizeof(iD) <= sizeof(newId), "!");
memcpy(&newId, &iD, sizeof(iD));这是完全定义好的行为。类型-通过union进行双关语不是。
https://stackoverflow.com/questions/36794736
复制相似问题