1. ホーム
  2. c++

[解決済み] 偽<真」という演算はきちんと定義されているのでしょうか?

2022-04-27 13:22:03

質問

C++の仕様で定義されているのか。

  1. 真偽値のパラメータに対する'less than'演算子の存在、および存在する場合。
  2. 4つのパラメータを並べ替えた結果は?

つまり、以下の操作による結果は、仕様で定義されているか?

false < false
false < true
true < false
true < true

私のセットアップ (Centos 7, gcc 4.8.2) では、以下のコードは私が期待するものを吐き出します (C が false を 0、true を 1 と表現する歴史を考慮しています)。

false < false = false
false < true = true
true < false = false
true < true = false

ほとんどの(すべての?)コンパイラが同じ出力をすることは間違いないと思いますが、これはC++の仕様で決められているのでしょうか?それとも、難読化しても仕様に準拠したコンパイラであれば、trueはfalseより小さいと判断してよいのでしょうか?

#include <iostream>

const char * s(bool a)
{
  return (a ? "true" : "false");
}

void test(bool a, bool b)
{
  std::cout << s(a) << " < " << s(b) << " = " << s(a < b) << std::endl;
}

int main(int argc, char* argv[])
{
  test(false, false);
  test(false, true);
  test(true, false);
  test(true, true);
  return 0;
}

解決方法は?

TL;DR。

C++標準のドラフトによると、操作はよく定義されています。

詳細

にアクセスすることで確認できます。 C++規格のドラフト セクション 5.9 関係演算子 というもので、( 今後ともよろしくお願いします ):

オペランドは算術演算が可能でなければならない。 またはポインタ タイプ またはstd::nullptr_t型です。演算子 < (以下)、 > (以上)、 <= (以下)、 >= (以上)は、すべて以下の結果をもたらします。 偽または真。結果の型はboolである

とboolsは3.9.1 Fundamental typesにあるarithematic typesです。

タイプ ブール char, char16_t, char32_t, wchar_t, および符号付き整数型と符号なし整数型は、一括して 積分型といいます。

そして

積分型と浮動型を総称して算術型と呼びます。 という型があります。

true そして false はブーリアンリテラルで 2.14.6 ブーリアンリテラルです。

boolean-literal:
    false
    true

セクションに戻る 5.9 を読んで、さらに関係演算子の仕組みを見てみると、こう書いてあります。

通常の算術変換は、算術型または列挙型のオペランドに対して行われます。

その 通常の算術変換 は、セクション 5 というのがある。

そうでなければ、積分促進(4.5)は、両方のオペランドに実行されなければならない

およびセクション 4.5 は言う。

bool型のprvalueはint型のprvalueに変換することができ、falseは0、trueは0になります。 が1になります。

というように、式があります。

false < false
false < true
true < false
true < true

となり、このルールが適用されます。

0 < 0
0 < 1
1 < 0
1 < 1