-1 を使用してすべてのビットを true に設定しても安全ですか?

あなたが示したとおりにそれを行うことをお勧めします。これが最も簡単な方法だからです。 -1 に初期化 常に動作します ~ の間、実際の符号表現とは無関係 正しいオペランド型が必要なため、驚くべき動作をすることがあります。そうして初めて unsigned の最高値が得られます タイプ。

考えられる驚きの例として、これを考えてみましょう:

unsigned long a = ~0u;

すべてのビットが 1 のパターンを a に保存するとは限りません。 .ただし、最初に unsigned int のすべてのビットが 1 のパターンを作成します。 、次にそれを a に割り当てます . unsigned long の場合 より多くのビットがあるということは、それらのすべてが 1 ではないということです。

そして、非 2 の補数表現では失敗する次の例を考えてみましょう:

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

その理由は ~0 すべてのビットを反転する必要があります。 -1 を生成する反転 2 の補数マシン (これが必要な値です!) では、しかし そうではありません 利回り -1 別の表現で。 1 の補数マシンでは、結果はゼロになります。したがって、1 の補数のマシンでは、上記は a を初期化します。 ゼロに。

理解しておくべきことは、ビットではなく値がすべてだということです。変数は value で初期化されます .初期化子で、初期化に使用される変数のビットを変更すると、それらのビットに従って値が生成されます。 a を初期化するために必要な値 可能な最大値は -1 です または UINT_MAX . 2 番目は a のタイプによって異なります。 - ULONG_MAX を使用する必要があります unsigned long の場合 .ただし、最初のものはそのタイプに依存せず、最も高い値を取得する良い方法です.

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

しかし、私たちが話しているのは、初期化された flags の結果です 変数は。そのためには、-1 のみ あらゆるタイプとマシンで動作します。


  • unsigned int flags = -1; ポータブルです。
  • unsigned int flags = ~0; 2 の補数表現に依存しているため、移植性がありません。
  • unsigned int flags = 0xffffffff; 32 ビット整数を想定しているため、移植性がありません。

C 標準で保証されている方法ですべてのビットを設定する場合は、最初のビットを使用してください。


率直に言って、すべての fff の方が読みやすいと思います。アンチパターンであるというコメントについては、すべてのビットが設定/クリアされていることを本当に気にしている場合は、とにかく変数のサイズを気にしている状況にあると思います.boostのようなものが必要になります. ::uint16_t など