我找到了将位字段用于网络消息的代码。我想知道转换 bitfield_struct data = *(bitfield_struct *)&tmp;
exaclty 的作用以及它的语法如何工作。不会违反严格的别名规则吗?这是部分代码:
typedef struct
{
unsigned var1 : 1;
unsigned var2 : 13;
unsigned var3 : 8;
unsigned var4 : 10;
unsigned var5 : 7;
unsigned var6 : 12;
unsigned var7 : 7;
unsigned var8 : 6;
} bitfield_struct;
void print_data(u_int64_t * raw, FILE * f, int no_object)
{
uint64_t tmp = ntohll(*raw);
bitfield_struct data = *(bitfield_struct *)&tmp;
...
}
最佳答案
Won't it violate the strict aliasing rule?
是的,所以代码会调用未定义的行为。它也非常不便携:
我们不知道给定系统使用的称为“可寻址存储单元”的抽象项的大小。它不一定是 64 位,因此理论上可能会在位字段中隐藏填充和其他令人讨厌的东西。 64 位
无符号
很可疑。我们也不知道位字段是否使用与
uint64_t
相同的位顺序。我们也不知道它们是否使用相同的字节顺序。
如果需要访问uint64_t
的各个位(字段),我建议使用按位移位来实现,因为这使得代码即使在不同的字节序架构之间也可以完全移植。那么您也不需要不可移植的 ntohll
调用。
关于在位域上转换 uint64_t,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59321863/