[英]How to set all bits of a bitfield member to 1
The question is pretty simple. 问题很简单。 Given 特定
struct Foo{
bool : 1;
bool : 1;
int bar : sizeof(int) * 8 - 2;
};
How can I set all bits of bar to 1, without a warning? 如何在不发出警告的情况下将bar的所有位设置为1?
Obviously I can do auto v = Foo(); v.bar = ~0;
显然我可以auto v = Foo(); v.bar = ~0;
auto v = Foo(); v.bar = ~0;
but GCC gives me this: 但海湾合作委员会给我这个:
warning: large integer implicitly truncated to unsigned type [-Woverflow]
I have tried a couple of ways, but it always renders a warning... 我尝试了几种方法,但是它总是会发出警告。
Don't use ~0
(which is always a full int
), but ~v.bar
, which is the right size and can be combined like so: 不要使用~0
(这始终是一个充满int
),但~v.bar
,这是正确的大小,可以组合,像这样:
v.bar |= ~v.bar; // or,
v.bar ^= ~v.bar;
should do the trick, for any size. 无论大小如何,都应该做到这一点。
Unfortunately you can't nicely wrap it in a function since you can't bind references to bitfields. 不幸的是,由于无法将引用绑定到位域,因此无法很好地将其包装在函数中。 You'd either need to make it a function on Foo&
, or use a macro. 您需要使其成为Foo&
上的函数,或者使用宏。
PS. PS。 I tried this quickly before posting with coliru , and just re-checked locally with GCC (g++) 5.3.1 and 6.2.0 - neither issue any diagnostic with -Wall
. 我在使用coliru进行发布之前很快尝试了此操作 ,只是在本地使用GCC(g ++)5.3.1和6.2.0重新进行了检查-均未使用-Wall
发出任何诊断信息。
PPS. PPS。
With this test code, GCC produces a diagnostic only for the unsigned member: 使用此测试代码,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]
*/
}
So although I'd also usually prefer unsigned integers for bitfields or for bitwise manipulation, g++ is happier and quieter with int
here. 因此,尽管我通常也更喜欢将无符号整数用于位域或按位操作,但g ++在这里使用int
更快乐,更安静。
This works for me for unsigned types. 这对我适用于无符号类型。 Note that all bit-fiddling should be done with unsigned types, unless you're OK with undefined behaviour. 请注意,所有位摆弄都应使用无符号类型完成,除非您对未定义的行为感到满意。
...
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>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.