1. ホーム
  2. c++

[解決済み] すべてのビットを真にするために-1を使用しても安全ですか?

2022-05-12 12:01:01

質問

このパターンはC&C++でよく使われているのを見かけます。

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

これは、これを達成するための良いポータブルな方法ですか? それとも 0xffffffff または ~0 の方が良いですか?

どのように解決するのですか?

表示されたとおりに実行するのが、最もわかりやすいのでおすすめです。初期化は -1 とすると、動作する 常に であり、実際の符号表現に依存しない。 ~ は正しいオペランド型を持っていなければならないので、時には驚くべき振る舞いをします。正しいオペランド型でなければならないからです。 unsigned 型の最も高い値を得ることができます。

考えられる驚きの例として、このようなものを考えてみましょう。

unsigned long a = ~0u;

必ずしもすべてのビットが 1 のパターンを a . しかし、これはまずすべてのビットが 1 のパターンを unsigned int に割り当て、それを a . このとき unsigned long がより多くのビットを持つ場合、それらのすべてが1であるとは限らないということです。

そして、2 の補数でない表現では失敗する、これを考えてみましょう。

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

その理由は ~0 はすべてのビットを反転させなければならないからです。それを反転させると -1 を得ますが(これは私たちが必要とする値です!)、しかし ではなく が得られます。 -1 は別の表現では 1の補数マシンでは0になる。したがって、1 の補数マシンでは、上記は初期化され a をゼロに初期化します。

理解していただきたいのは、これはすべて値についてだということです - ビットではありません。変数の初期化には . もしイニシャライザーの中で、初期化に使われる変数のビットを変更すれば、そのビットに応じた値が生成されます。初期化するために必要な値は a を可能な限り高い値に初期化するために必要な値は、次のとおりです。 -1 または UINT_MAX . もうひとつは a - を使用する必要があります。 ULONG_MAX に対して unsigned long . しかし、1つ目はその型に依存しないでしょうし、最も高い値を得るには良い方法です。

私たちは ではない を話しているのではありません。 -1 がすべてのビットを1つ持っているかどうかを話しているのではありません(常に持っているわけではありません)。そして、私たちは ではない であるかどうかを話しているのです。 ~0 がすべてのビットを 1 にするかどうかを話しているのではありません (もちろん、1 にしています)。

しかし、私たちが話しているのは、初期化された flags 変数がどうなるかということです。そしてそれに対して だけ -1 は、あらゆるタイプやマシンで動作します。