c - 在位域上转换 uint64_t
问题描述
我找到了位域用于网络消息的代码。我想知道强制转换 bitfield_struct data = *(bitfield_struct *)&tmp;
的作用以及它的语法是如何工作的。它不会违反严格的别名规则吗?以下是部分代码:
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;
...
}
解决方案
它不会违反严格的别名规则吗?
是的,它会,所以代码会调用未定义的行为。它也非常不便携:
我们不知道给定系统使用的称为“可寻址存储单元”的抽象项目的大小。它不一定是 64 位,所以理论上可能有填充和其他隐藏在位域中的讨厌的东西。64位
unsigned
是可疑的。我们也不知道位域是否使用与 相同的位序
uint64_t
。我们也不知道他们是否使用相同的字节序。
uint64_t
如果需要访问单个位(字段) ,我建议使用按位移位来访问,因为这使得代码即使在不同的字节序架构之间也完全可移植。那么你也不需要非便携式ntohll
电话。
推荐阅读
- deep-learning - 为什么在使用深度学习训练目标检测器时需要忽略锚点?
- c++ - 如何根据用户输入多次调用 c++ 函数?
- regex - 只需要匹配正则表达式中数据包的第二次出现
- php - Eloquent 急切加载不返回相关模型数据
- php - 向搜索建议添加功能(Savoy Theme、Woocommerce)
- python - 如何添加两个连续小时之间发生的值?
- r - 如何复制一行并粘贴为重复的列?
- android - 应用程序关闭时如何接收通知?
- javascript - 在“:”之后输入 0 到 59 之间的两位数字
- python - 如何纠正以下一名玩家的tictactoe游戏?