如何将位域成员的所有位设置为 1
How to set all bits of a bitfield member to 1
这个问题很简单。鉴于
struct Foo{
bool : 1;
bool : 1;
int bar : sizeof(int) * 8 - 2;
};
如何在没有警告的情况下将所有柱线位设置为 1?
显然我可以做auto v = Foo(); v.bar = ~0;
但 GCC 给了我这个:
warning: large integer implicitly truncated to unsigned type [-Woverflow]
我已经尝试了几种方法,但它总是发出警告......
不要使用 ~0
(它始终是一个完整的int
(,而是~v.bar
,这是正确的大小,可以像这样组合:
v.bar |= ~v.bar; // or,
v.bar ^= ~v.bar;
应该做这个伎俩,适合任何尺寸。
不幸的是,您无法很好地将其包装在函数中,因为您无法将引用绑定到位字段。你要么需要让它成为Foo&
上的函数,要么使用宏。
附言。在使用 coliru 发布之前,我快速尝试了这个,并且只是使用 GCC (g++( 5.3.1 和 6.2.0 在本地重新检查 - 两者都没有发出任何诊断-Wall
。
.PPS。
使用此测试代码,GCC 仅为未签名的成员生成诊断:
struct Foo {
int i : 2;
unsigned int u : 30;
};
void bar() {
Foo f {0, 0};
f.i ^= ~f.i; // OK
f.u |= ~f.u; /* warning:
large integer implicitly truncated to unsigned type [-Woverflow]
*/
}
因此,尽管我通常也更喜欢位字段或按位操作的无符号整数,但 g++ 在这里使用int
更快乐、更安静。
这对我无符号类型有用。请注意,所有位摆弄都应该使用无符号类型完成,除非你对未定义的行为感到满意。
...
unsigned int bar : sizeof(int) * 8 - 2;
...
template <typename T, unsigned n>
constexpr T onebits()
{
return 1 | (((1 << (n-2)) - 1) << 1);
}
v.bar = onebits<unsigned, sizeof(int) * 8 - 2>();
相关文章:
- C++Union/Struct位域的实现和可移植性
- 具有位域的结构的 Constexpr 构造函数
- 如何解释 #if/#else 位域?(VC++菜鸟)
- 枚举位域和聚合初始化
- 在有符号基础类型枚举的位域上溢出
- 给定一个整数 N>0,区间 [0, 2^N) 中有多少个整数正好有 N-1 个设置位?编写一个返回正确答案的简短函数
- 哪个是设置位的最佳方法以及为什么?
- 如何为具有整数名称的变量设置位集
- 如何检查位域是否跨越所有位
- 访问位域联合是C++标准中常见的初始数据未定义行为
- 位操作将最左侧的设置位转换为右侧交替位?
- 如何设置位?
- 找到非常大的数字的最右边的未设置位
- 锈迹位域和枚举C++样式
- C/C++:uint8_t位域的行为不正确且不一致
- 如何将位域写入二进制文件
- 如何获取设置位中的相对位置
- 字节序和大小为 1 的位域
- 面向对象编程 - 位域私有结构的公共参考
- 如何将位域成员的所有位设置为 1