C++仕様では以下を定義していますか?
つまり、次の操作の結果は仕様で定義されていますか?
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
関係演算子に進むと、(エンファシスマイニングフォワード)と表示されます。
オペランドには、算術、列挙、またはポインターtype、またはtype std :: nullptr_t。演算子<(より小さい)、>(より大きい)、<=(以下)、および> =(以上)はすべてfalseまたはtrueを返します。結果の型はブールです
およびboolは、3.9.1基本型の算術型です。
型bool、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はゼロになり、trueは1になります。
そして、式:
false < false
false < true
true < false
true < true
これらのルールを使用すると、次のようになります。
0 < 0
0 < 1
1 < 0
1 < 1
ブール値は通常の整数プロモーションの対象となり、false
は0
として定義され、true
は1
として定義されます。これにより、すべての比較が適切に定義されます。
C++標準(5.9関係演算子)による
2通常の算術変換は、算術型または列挙型のオペランドに対して実行されます。
そして
1 ...結果の型はブールです。
および(3.9.1基本タイプ)
6 bool型の値はtrueまたはfalseのいずれかです。49[注:符号付き、符号なし、short、またはlongのブール型または値はありません。 —エンドノート] bool型の値は整数型プロモーションに参加します(4.5)。
(4.5インテグラルプロモーション)
6 bool型のprvalueは、falseがゼロになり、trueが1になるで、int型のprvalueに変換できます。
すべての例で、trueはint 1に変換され、falseはint 0に変換されます
これらの表現
false < false
false < true
true < false
true < true
と完全に同等です
0 < 0
0 < 1
1 < 0
1 < 1
ブールfalse
はint 0
と同等であり、ブールtrue
はint 1
と同等です。したがって、これは、式false < true
=> 0 < 1
がtrue
を返す唯一のものである理由を説明しています。