【发布时间】:2020-03-18 10:05:38
【问题描述】:
我在 c 中有一个这样的结构
struct RegisterStruct
{
uint64_t b_0 : 64;
uint64_t b_1 : 64;
uint64_t c_0 : 64;
uint64_t c_1 : 64;
uint64_t c_2 : 64;
uint64_t d_0 : 64;
uint64_t d_1 : 64;
};
我想将这些字段连接成一个uint64_t 整数。每个字段应占用给定的位数,定义如下:
b_0: 4bits
b_1: 4bits
c_0: 8bits
c_1: 8bits
c_2: 8bits
d_1: 16bits
d_2: 16bits
结果应该是一个uint64_t 整数,其中包含连接的位字段(从b_0 到d_2),每个位字段占用给定的位数。
这是我尝试过的,但我认为这个解决方案不正确:
struct RegisterStruct Register;
Register.b_0 = 8;
Register.b_1 = 8;
Register.c_0 = 128;
Register.c_1 = 128;
Register.c_2 = 128;
Register.d_0 = 32768;
Register.d_1 = 32768;
uint64_t reg_frame =Register.b_0<<60|Register.b_1<<56|Register.c_0<<48|Register.c_1<<40|Register.c_2<<32|Register.d_0<<16|Register.d_1;
【问题讨论】:
-
"...但我认为这个解决方案不正确" 为什么它不正确?你遇到了什么问题?
-
在您发布的
struct RegisterStruct中,所有位域宽度均为64。这是剪切和粘贴错误吗?您确定要它们为 4、4、8、8、8、16 和 16? -
您的解决方案是正确的。我自然会从最低有效位理解位顺序,所以我会将
b_0: 4bits作为最低有效位。 -
如果您移动位域,请将它们转换为足够宽度的无符号整数类型,即使声明它们的基类型是这样的类型。作为we have seen recently,C 标准不清楚位域的实际类型是什么,因此
uint64_t x : 4可能像(例如)表达式中的32 位int,然后是Register.x << 60将有一个超出int界限的移位量并且具有C 标准未定义的行为。 -
@Kinyugo 我看不出将所有位域设为 64 位宽的意义。它们将(可能)与非位字段
uint64_t成员的行为相同。
标签: c bit-manipulation bit bit-shift