使用 -1 将所有位设置为真是否安全?

2022-01-09 00:00:00 binary c bit-fields c++

我已经看到这种模式在 C &C++.

I've seen this pattern used a lot in C & C++.

unsigned int flags = -1;  // all bits are true

这是实现此目的的一种很好的便携方式吗?还是使用 0xffffffff~0 更好?

Is this a good portable way to accomplish this? Or is using 0xffffffff or ~0 better?

推荐答案

我建议你完全按照你展示的那样去做,因为它是最直接的.初始化为 -1 它将工作 always,独立于实际的符号表示,而 ~ 有时会出现令人惊讶的行为,因为您必须拥有正确的操作数类型.只有这样,您才能获得 unsigned 类型的最高值.

I recommend you to do it exactly as you have shown, since it is the most straight forward one. Initialize to -1 which will work always, independent of the actual sign representation, while ~ will sometimes have surprising behavior because you will have to have the right operand type. Only then you will get the most high value of an unsigned type.

关于可能的惊喜的示例,请考虑以下示例:

For an example of a possible surprise, consider this one:

unsigned long a = ~0u;

它不一定会将所有位为 1 的模式存储到 a 中.但它会首先在 unsigned int 中创建一个所有位为 1 的模式,然后将其分配给 a.当 unsigned long 有更多位时会发生什么,并不是所有位都是 1.

It won't necessarily store a pattern with all bits 1 into a. But it will first create a pattern with all bits 1 in an unsigned int, and then assign it to a. What happens when unsigned long has more bits is that not all of those are 1.

考虑一下这个,它在非二进制补码表示上会失败:

And consider this one, which will fail on a non-two's complement representation:

unsigned int a = ~0; // Should have done ~0u !

原因是 ~0 必须反转所有位.反转将在二进制补码机器上产生 -1 (这是我们需要的值!),但在另一个机器上 not 产生 -1表示.在一个补码机器上,它产生零.因此,在一个补码机器上,上面的代码会将 a 初始化为零.

The reason for that is that ~0 has to invert all bits. Inverting that will yield -1 on a two's complement machine (which is the value we need!), but will not yield -1 on another representation. On a one's complement machine, it yields zero. Thus, on a one's complement machine, the above will initialize a to zero.

您应该理解的是,这一切都与价值有关,而不是位.该变量使用 value 进行初始化.如果在初始化程序中修改了用于初始化的变量的位,则将根据这些位生成值.将 a 初始化为可能的最高值所需的值是 -1UINT_MAX.第二个将取决于 a 的类型 - 您需要将 ULONG_MAX 用于 unsigned long.但是,第一个不依赖于它的类型,这是获得最高值的好方法.

The thing you should understand is that it's all about values - not bits. The variable is initialized with a value. If in the initializer you modify the bits of the variable used for initialization, the value will be generated according to those bits. The value you need, to initialize a to the highest possible value, is -1 or UINT_MAX. The second will depend on the type of a - you will need to use ULONG_MAX for an unsigned long. However, the first will not depend on its type, and it's a nice way of getting the most highest value.

我们不是在讨论 -1 是否所有位都为一(并非总是如此).我们不是在讨论 ~0 是否所有位都为一(当然是).

We are not talking about whether -1 has all bits one (it doesn't always have). And we're not talking about whether ~0 has all bits one (it has, of course).

但是我们说的是初始化flags变量的结果是什么.而对于它,只有 -1 可以适用于所有类型和机器.

But what we are talking about is what the result of the initialized flags variable is. And for it, only -1 will work with every type and machine.

相关文章