- これでいいですか?(これは g++ 4.3.3 でテストされました)つまり、コンパイラは、ブール値の比較中にゼロ以外の値が true を意味する可能性があることに注意する必要がありますか?
ゼロ以外の整数値 (または NULL 以外のポインター) はすべて true を表します。ただし、integer と bool を比較する場合、bool は比較前に int に変換されます。
- このコーナーケースが実際の問題になる可能性があるケースを知っていますか? (たとえば、ストリームからのデータのバイナリ読み込み中)
それは常に現実的な問題です。
これでいいですか?
仕様がこれについて何かを指定しているかどうかはわかりません。コンパイラは常に次のようなコードを作成する可能性があります: ((a!=0) && (b!=0)) || ((a==0) && (b==0)) は、2 つのブール値を比較する場合に使用されますが、パフォーマンスが低下する可能性があります。
私の意見では、これはバグではなく、未定義の動作です。すべての実装者は、実装でブール比較がどのように行われるかをユーザーに伝える必要があると思います。
最後のコード サンプルを見ると、a と b の両方がブール値であり、1 と 2 を適切に割り当てることで true に設定されます (いいえ、1 と 2 が消えると、それらは単に true になります)。
だからあなたの表現を分解する:
a!=0 // true (a converted to 1 because of auto-type conversion)
b!=0 // true (b converted to 1 because of auto-type conversion)
((a!=0) && (b!=0)) => (true && true) // true ( no conversion done)
a==0 // false (a converted to 1 because of auto-type conversion)
b==0 // false (b converted to 1 because of auto-type conversion)
((a==0) && (b==0)) => (false && false) // false ( no conversion done)
((a!=0) && (b!=0)) || ((a==0) && (b==0)) => (true || false) => true
したがって、上記の式が明確に定義され、常に真であることを常に期待しています。
しかし、これが元の質問にどのように当てはまるかわかりません。整数を bool に代入すると、整数は bool に変換されます (何度か説明したように)。true の実際の表現は標準で定義されておらず、bool に適合する任意のビット パターンである可能性があります (特定のビット パターンを仮定しない場合があります)。
bool を int と比較する場合、bool はまず int に変換されてから比較されます。
あらゆる現実のケース
私の頭に浮かぶ唯一のことは、誰かがファイルからブールメンバーを持つ構造体にバイナリデータを読み取った場合です。bool の場所に 1 ではなく 2 を書き込んだ他のプログラムでファイルが作成された場合、問題が発生する可能性があります (別のプログラミング言語で作成された可能性があります)。
しかし、これは悪いプログラミング手法を意味するかもしれません。
バイナリ形式でのデータの書き込みは、知識がなければ移植できません。
各オブジェクトのサイズに問題があります。
表現には問題があります:
- 整数 (エンディアンあり)
- Float (未定義の表現 ((通常は基盤となるハードウェアに依存))
- Bool (バイナリ表現は標準で定義されていません)
- 構造体 (メンバー間のパディングは異なる場合があります)
これらすべてについて、基礎となるハードウェアとコンパイラについて知る必要があります。異なるコンパイラまたはコンパイラの異なるバージョン、または異なる最適化フラグを持つコンパイラでさえ、上記のすべてに対して異なる動作をする可能性があります。
ユニオンの問題
struct X
{
int a;
bool b;
};
人々が「a」への書き込みと「b」からの読み取りについて言及しているように、定義されていません。
理由: このハードウェアで「a」または「b」がどのように表現されるかがわからないためです。「a」に書き込むと「a」のビットが埋められますが、「b」のビットにはどのように反映されますか。システムが 1 バイトの bool と 4 バイトの int を使用し、最下位バイトが下位メモリに最上位バイトが上位メモリにある場合、「a」に 1 を書き込むと「b」に 1 が書き込まれます。しかし、実装はどのようにブール値を表していますか? true は 1 または 255 で表されますか? 'b' に 1 を入れ、それ以外のすべての true の使用に 255 を使用するとどうなりますか?
したがって、ハードウェアとコンパイラの両方を理解していないと、予期しない動作になります。
したがって、これらの使用法は定義されていませんが、標準では禁止されていません。それらが許可されている理由は、調査を行った結果、この特定のコンパイラを使用するシステムでは、これらの仮定を行うことで、気まぐれな最適化を行うことができることがわかったからです。ただし、前提条件を変更すると、コードが破損することに注意してください。
また、2 つの型を比較する場合、コンパイラは比較の前にいくつかの自動変換を行います。2 つの型は比較の前に同じ型に変換されることに注意してください。整数と bool の比較では、bool が整数に変換され、他の整数と比較されます (変換により、false が 0 に、true が 1 に変換されます)。変換されるオブジェクトが両方とも bool である場合、変換は不要であり、ブール論理を使用して比較が行われます。