あなたが示したとおりにそれを行うことをお勧めします。これが最も簡単な方法だからです。 -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 など