CおよびC++では、ブールをintにキャストするとき、_(int)true == 1
_および_(int)false == 0
_を知っています。私は逆方向にキャストすることを考えています...
以下のコードでは、Visual Studio 2013およびKeil µVision 5でコンパイルされた.cファイルで、以下のすべてのアサーションが当てはまりました。_(bool)2 == true
_に注意してください。
CおよびC++標準は、非ゼロ、非1整数をブールにキャストすることについて何と言っていますか?この動作は指定されていますか?引用を含めてください。
_#include <stdbool.h>
#include <assert.h>
void TestBoolCast(void)
{
int i0 = 0, i1 = 1, i2 = 2;
assert((bool)i0 == false);
assert((bool)i1 == true);
assert((bool)i2 == true);
assert(!!i0 == false);
assert(!!i1 == true);
assert(!!i2 == true);
}
_
NotC++コンパイラでは(bool)true ==(int)1と仮定できますか? :
基本型の0値 (1)(2)false
にマップします。
他の値はtrue
にマップされます。
この規則は、フロー制御ステートメントを介して、元のCで確立されました。 Cは、その時点ではブール型を持っていませんでした。
関数の戻り値としてfalse
が失敗を示すと仮定することはよくあるエラーです。しかし、特にmain
からは、成功を示すのはfalse
です。 D言語のWindowsスターターコードを含め、これが何度も間違っているのを見てきました(Walter BrightやAndrei Alexandrescuのような人々が間違っている場合、それはただeasy間違っている)、したがって、このヘッズアップは注意してください。
組み込み型の場合、変換は暗黙的であるため、bool
にキャストする必要はありません。ただし、Visual C++(MicrosoftのC++コンパイラ)は、これに対してパフォーマンス警告(!)を発行する傾向があります。これは純粋に愚かな警告です。キャストはそれを閉じるのに十分ではありませんが、二重否定による変換、つまりreturn !!x
はうまく機能します。 !!
を「goes to」として読み取ることができるのと同様に、-->
を「bool
に変換」演算子として読み取ることができます。演算子表記の読みやすさに深く関わっている人向け。 ;-)
1) C++ 14§4.12/ 1「ゼロ値、ヌルポインター値、またはヌルメンバーポインター値はfalse
に変換されます。その他の値はtrue
に変換されます。直接初期化(8.5)の場合、タイプstd::nullptr_t
のprvalueは、タイプbool
のprvalueに変換できます。結果の値はfalse
です。」
2) C99およびC11§6.3.1.2/ 1「スカラー値が_Bool
に変換される場合、値が0と等しい場合、結果は0です。それ以外の場合、結果は1です。」
以下はC11標準(最終ドラフト)を引用しています。
6.3.1.2: スカラー値が_Boolに変換されるとき、値が0と等しい場合、結果は0です。それ以外の場合、結果は1です。
bool
(Cのstdbool.h
によって内部名_Bool
にマッピングされます)自体は 符号なし整数型 :
... _Bool型および標準の符号付き整数型に対応する符号なし整数型は、標準の符号なし整数型です。
6.2.5p2 によると:
タイプ_Boolとして宣言されたオブジェクトは、値0および1を格納するのに十分な大きさです。
私の知る限り、これらの定義はC++と意味的に同一です-組み込み(!)名のわずかな違いを除いて。 C++の場合はbool
、Cの場合は_Bool
.
Cでは、C++のように rvalues という用語を使用しないことに注意してください。ただし、Cでは、ポインターはスカラーであるため、_Bool
へのポインターの割り当ては、C++と同様に動作します。
(少なくともMS Visual Studio 2019 C++では)警告を削除する別の方法は、三項演算子を使用して、値をtrueまたはfalseに直接設定することです。
int i = 3; // Or another value
bool b = (i ? true : false);
または、より明確にするために:
int i = 3; // Or another value
bool b = (i == 0 ? false : true);