在位域上铸造uint64_t

问题描述 投票:0回答:2

我找到了将位字段用于网络消息的代码。我想知道强制转换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;

    ...
}
c casting endianness bit-fields strict-aliasing
2个回答
0
投票

是否违反严格的别名规则?

是的,因此代码将调用未定义的行为。它也是高度不可移植的:

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

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

如果需要访问uint64_t的各个位(字段),我建议使用按位移位,因为即使在不同的字节序体系结构之间,代码也可以完全移植。然后,您也不需要非便携式的ntohll调用。


-2
投票

从右到左:

[&tmp取得tmp的地址

(bitfield_struct *)&tmp tmp的地址是指向bitfield_struct类型数据的地址

[*(bitfield_struct *)&tmp从tmp提取值,假设它是bitfield_struct数据

bitfield_struct data = *(bitfield_struct *)&tmp;将tmp存储到数据,假设tmp是bitfield_struct

因此,它只是使用多余的指针进行复制,以避免编译错误/不兼容类型的警告。

您可能不了解的是结构的位寻址。

unsigned var1 : 1; unsigned var2 : 13;

在这里您将找到有关它的更多信息:https://www.tutorialspoint.com/cprogramming/c_bit_fields.htm

© www.soinside.com 2019 - 2024. All rights reserved.