说我有这样的位域:
struct SomeStruct {
uint32_t first : 12;
uint32_t second : 2;
uint32_t third : 18;
};
SomeStruct obj;
我想分配
obj.second = 3; // Actually, the maximum allowed value
实现这一目标的便携方式是什么? 我也不想明确使用已知的位域宽度。
我的代码
obj.second = std::numeric_limits<uint32_t>::max()
但与-Wbitfield-constant-conversion
发出警告会发出警告并cpp reference states:
位字段的以下属性是实现定义的 使用a分配或初始化位字段所产生的值 值超出范围,或者增加超出其范围的位字段。
那么分配-1
或numeric_limits<uint32_t>::max()
实际上是便携式还是有其他方式?
答案 0 :(得分:2)
如果有两位,则最大值为2 2 -1。获得该值的一种简单方法是将1
向左移动两步(给出2 2 )并减去1。
因此2位的最大值为(1U << 2) - 1
。
它可以在所有C编译器之间移植,并且编译器将能够优化操作,因此赋值仅适用于结果值。
答案 1 :(得分:2)
由于字段是无符号的,因此工作很简单:
obj.second = -1;
无符号算术可以很好地定义,即使对于位域也是如此。
答案 2 :(得分:1)
CWG 1816清楚地指出了一个不能用位字表示的值,结果值是实现定义的。
我担心,我不知道任何可移植的方式来实现你想要的东西。
答案 3 :(得分:0)
对于无符号整数类型:
unsigned char max = ~0;
在英语中,零补码将所有位设置为1,这是该类型的最大无符号值。
当您使用位域时,这种简单的方法可能对您不起作用。如果您使用:
struct SomeStruct {
uint8_t first;
uint8_t second;
uint8_t third;
};
然后它可能是一个选项。
答案 4 :(得分:0)
最好的方法是分配-1
/ -1L
/ ~0
/ ~0L
或INT_MAX
/ LONG_MAX
。
但是这段代码依赖于当今计算机中整数的表示方式。这在任何地方都有效,但正式来自C标准规范是不可移植的。