简体   繁体   English

布尔值的排序

[英]Ordering of boolean values

Under C++ or <stdbool.h> from C99, how is the less-than operator < defined for boolean values? 下C ++或<stdbool.h>从C99,怎么是小于操作符<布尔值定义?

Alternatively, explain the behaviour of this code: 或者,解释此代码的行为:

#ifndef __cplusplus
#include <stdbool.h>
#endif
#include <stdio.h>

int main() {
    bool b = -1;
    if(b < true) {
        printf("b < true\n");
    }
    if(b < false) {
        printf("b < false\n");
    }
    if(true < false) {
        printf("true < false\n");
    }
    if(false < true) {
        printf("false < true\n");
    }
}

Under MSVC version 10, compiled as C++ code, GCC 4.6.3-ubuntu5 compiled as C code and G++ 4.6.3-1ubuntu5 compiled as C++ code, all you get is 在MSVC版本10下,编译为C ++代码,编译为C代码的GCC 4.6.3-ubuntu5和编译为C ++代码的G ++ 4.6.3-1ubuntu5,所有你得到的是

false < true

That is, the following inequalities are all false : 也就是说,以下不等式都是false

(bool)-1 < true
(bool)-1 < false
true < false

And the following is true : 以下是true

false < true

In C++ (and I suspect in C as well), bool s compare exactly as if false were 0 and true were 1 . 在C ++中(我也怀疑在C语言中), bool的比较完全如同false0true1 And if the type is bool , no values other than true and false are possible. 如果类型是bool ,则除了truefalse之外的值都不可能。

When comparing bool to other numeric types, it will convert to int , again with false converting to 0 and true converting to 1 . bool与其他数值类型进行比较时,它将转换为int ,同样将false转换为0并将true转换为1

Edit: Both C++ and stdbool.h in C99 also force boolean values to be either 0 (false) or 1 (true) - bool b = -1; 编辑: C99中的C ++和stdbool.h也强制布尔值为0(假)或1(真) - bool b = -1; sets the value of b to 1. Since 1 < 1 and 1 < 0 are both false, the inequalities in the question are correct. b的值设置为1.由于1 < 11 < 0都是假的,因此问题中的不等式是正确的。

Edit: (by James) Except that the above edit isn't really correct, at least for C++. 编辑:(由詹姆斯)除了上面的编辑不是真的正确,至少对于C ++。 A bool doesn't have a value of 0 or 1, it has a value of false or true . bool的值不是0或1,它的值为falsetrue It's only when it is promoted to int that the conversion creates the values of 0 and 1 . 只有当它被提升为int ,转换才会创建01的值。

And as Konrad has pointed out, there is no conparison of bool values. 正如康拉德指出的那样,没有bool值的比较。 The "usual arithmetic conversions" occur for the comparison operators, which means integral promotion on both of the operands, which means bool converts to int (as does char or short ... or an enum). 比较运算符出现“通常的算术转换”,这意味着两个操作数的整体提升,这意味着bool转换为int (如charshort ...或枚举)。

All of which is rather technical. 所有这些都是技术性的。 In practice, you can remember that false < true , or you can consider false is 0 and true is 1, whichever works best for you. 在实践中,你可以记住false < true ,或者你可以认为false是0而true是1,哪个最适合你。 The only important thing to remember is that a bool can have no other values. 要记住的唯一重要的事情是bool 没有其他值。

(Interestingly, I don't think that the bit patterns of a bool are imposed by the standard. An implementation could use the bit patterns 0x55 and 0xAA , for example, as long as all conversions to an integral type gave 0 and 1, conversion to bool always gave the appropriate value, etc. Including zero initialization of static variables.) (有趣的是,我不认为bool的位模式是由标准强加的。例如,一个实现可以使用位模式0x550xAA ,只要所有转换为整数类型给出0和1,转换bool总是给出适当的值等。包括静态变量的零初始化。)

And one final note: bool b = -1; 最后一点是: bool b = -1; sets b to -1 != 0 (which is true , not 1 , but of course, true will convert to 1 in any numeric context. b设置为-1 != 0 (这是true ,不是1 ,但当然, true会在任何数字上下文中转换为1

This makes perfect sense. 这很有道理。 The integral type => bool conversion is effectively b = i != 0 . 积分类型=> bool转换实际上是b = i != 0 In order to do the < comparison it promotes the bool to int by the rule false=>0 and true=>1. 为了进行<比较,它通过规则false => 0和true => 1将bool提升为int。 In your first case -1 will equate to true, and both will promote to 1 so it's false. 在你的第一种情况下, -1将等于true,并且两者都将提升为1,因此它是错误的。 Obviously 1 is never less than 0 for the second and third cases, while 0 < 1 in the last case. 显然,对于第二和第三种情况,1永远不会小于0,而在最后一种情况下0 < 1

Boolean values are ordered such that false is smaller than true . 对布尔值进行排序,使得false小于true According to the standard, a bool can only hold two values: true and false , so the conversions in (bool)-1 should have yielded true (as all non-0 values when converted to bool are true ). 根据标准, bool只能包含两个值: truefalse ,因此(bool)-1的转换应该产生true (因为转换为bool时所有非0值都为true )。 That is the behavior in clang and g++-4.7. 这就是clang和g ++ - 4.7中的行为。

The actual comparison (I believe) is done on int after the bool is promoted, and it seems that the compilers you tested avoided the intermediate step of converting through bool and just promoted the actual bool value. 实际比较(我相信)是在bool升级后在int完成的,看来你测试的编译器避免了通过bool转换的中间步骤,只是提升了实际的bool值。

operator > and < base on this: operator>和<基于此:

true == (1)
false == (0)

this false: (bool)-1 < true (bool)-1 < false because of rolling arithmetic in bool b = -1; 这个假:(bool)-1 <true(bool)-1 <false因为bool中的滚动算术b = -1;

bool seems to be defined as a (signed) integer type, false being 0, zero being 1. This explains why true > false (1 > 0) is true. bool似乎被定义为(带符号)整数类型,false为0,零为1.这解释了为什么true> false(1> 0)为真。

Also, comparing -1 to an unsigned number makes -1 be cast to unsigned, and on your platform this causes an integer overflow, resulting UINT_MAX (or whichever type bool has been typedeffed to). 此外,将-1与无符号数进行比较会使-1转换为无符号,并且在您的平台上会导致整数溢出,从而产生UINT_MAX(或者类型为bool的类型)。 This now explains why the following expressions were false: 这现在解释了为什么以下表达式是错误的:

((bool)-1) < true i. e. UINT_MAX < 1
((bool)-1) < false i. e. UINT_MAX < 0
true < false i. e. 1 < 0

For C++ just false < true 对于C ++,只是false < true

For C is more difficult to answer. 因为C更难回答。 I see 我知道了

typedef char _Bool; /* For C compilers without _Bool */ typedef char _Bool; /* For C compilers without _Bool */ in my stdbool.h typedef char _Bool; /* For C compilers without _Bool */我的stdbool.h中typedef char _Bool; /* For C compilers without _Bool */

Seems, that if compiler support _Bool , it works as in C++ and automatically converts to 0/1, but if not it should work as char and it'll be b < true , b < false if char is signed 似乎,如果编译器支持_Bool ,它就像在C ++中一样工作并自动转换为0/1,但如果不是,它应该作为char工作,它将是b < trueb < false如果char被签名

For me (int)(bool) -1 is 1 even in C, so bool is defined as not char 对于我(int)(bool)-1即使在C中也是1,所以bool被定义为不是char

Here is an explaination, I haven't checked with the standard though. 这是一个解释,我没有用标准检查过。 From your experiments it seems that the "<" operator is not defined for boolean values. 从您的实验中,似乎没有为布尔值定义“<”运算符。 What is compared is the unsigned ints that the booleans are converted to. 比较的是布尔值被转换为的无符号整数。 In theory it could be possible that the standard doesn't guarantee that all "true" booleans are converted to the same value. 从理论上讲,标准可能无法保证所有“真正的”布尔值都转换为相同的值。 And -1 is converted to the largest unsigned int. 并且-1被转换为最大的unsigned int。

As another experiment, the following code 作为另一个实验,以下代码

#include <iostream>

int main()
{
std::cout<< (((bool)1) == true) << "\n";
std::cout<< (((bool)2) == true) << "\n";
std::cout<< (((bool)0) == false) << "\n";
std::cout<< (((bool)1) == false) << "\n";
  return 0;
}

prints 1 1 1 0 打印1 1 1 0

So any nonzero value is "true". 所以任何非零值都是“true”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM