web-dev-qa-db-ja.com

C / C ++でintをブールにキャスト

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と仮定できますか?

  1. 逆方向のキャスト(int-> bool)。
  2. 非ゼロ、非1の値についての議論はありません。
26
cp.engr

基本型の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です。」

34

以下は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);
0
Michel Keijzers