首页 > 解决方案 > 在位域上转换 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;

    ...
}

标签: ccastingendiannessbit-fieldsstrict-aliasing

解决方案


它不会违反严格的别名规则吗?

是的,它会,所以代码会调用未定义的行为。它也非常不便携:

  • 我们不知道给定系统使用的称为“可寻址存储单元”的抽象项目的大小。它不一定是 64 位,所以理论上可能有填充和其他隐藏在位域中的讨厌的东西。64位unsigned是可疑的。

  • 我们也不知道位域是否使用与 相同的位序uint64_t。我们也不知道他们是否使用相同的字节序。

uint64_t如果需要访问单个位(字段) ,我建议使用按位移位来访问,因为这使得代码即使在不同的字节序架构之间也完全可移植。那么你也不需要非便携式ntohll电话。


推荐阅读