在C ++或C99的<stdbool.h>
下,如何为布尔值定义小于运算符<
?
或者,解释此代码的行为:
#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");
}
}
在MSVC版本10下,编译为C ++代码,编译为C代码的GCC 4.6.3-ubuntu5和编译为C ++代码的G ++ 4.6.3-1ubuntu5,所有你得到的是
false < true
即,以下不等式都是false
:
(bool)-1 < true
(bool)-1 < false
true < false
以下是true
:
false < true
答案 0 :(得分:15)
在C ++中(我也怀疑在C中),bool
完全比较
false
0
true
为1
bool
。如果类型为true
,则为
false
和bool
以外的值是可能的。
将int
与其他数字类型进行比较时,它会转换为false
,
再次将0
转换为true
并1
转换为stdbool.h
。
编辑: C99中的C ++和bool b = -1;
也强制布尔值为0(假)或1(真) - b
设置{{1}的值1}}到1.由于1 < 1
和1 < 0
都是假的,因此问题中的不等式是正确的。
编辑(由James撰写)除了以上编辑不是真的正确之外,在
至少对C ++而言。 bool
的值不是0或1,它有一个值
false
或true
。只有当它被提升到int
时才会被提升
转化会创建0
和1
的值。
正如康拉德指出的那样,没有bool
值的比较。
比较运算符发生“通常的算术转换”,
这意味着对两个操作数进行整体提升
bool
转换为int
(char
或short
...或枚举)。
所有这些都是技术性的。在实践中,你可以记住这一点
false
&lt; true
,或者您可以认为false
为0且true
为1,
哪个最适合你。要记住的唯一重要的事情是
bool
可以否其他值。
(有趣的是,我不认为bool
的位模式
标准强加的。实现可以使用位模式
例如,0x55
和0xAA
,只要所有转化为
积分类型给出0和1,转换为bool
总是给出
适当的值等。包括静态零初始化
变量。)
最后一条注释:bool b = -1;
将b
设置为-1 != 0
(即{}
true
,而非1
,但当然,true
会转换为1
数字上下文。
答案 1 :(得分:4)
这很有道理。积分类型=&gt; bool转换实际上是b = i != 0
。为了进行<
比较,它通过规则false =&gt; 0和true =&gt; 1将bool提升为int。在你的第一种情况下,-1
将等同于true,并且两者都将提升为1,因此它是错误的。显然,对于第二种和第三种情况,1永远不会小于0,而在最后一种情况下则为0 < 1
。
答案 2 :(得分:2)
对布尔值进行排序,使false
小于true
。根据标准,bool
只能包含两个值:true
和false
,因此(bool)-1
中的转化应该产生true
(因为所有非转换为bool时的-0值为true
)。这就是clang和g ++ - 4.7中的行为。
实际比较(我相信)是在int
被提升之后在bool
上完成的,并且您测试的编译器似乎避免了通过bool进行转换的中间步骤而只是提升了实际{ {1}}值。
答案 3 :(得分:1)
运算符&gt;和&lt;基于此:
true == (1)
false == (0)
这个错误: (bool)-1&lt;真正 (bool)-1&lt;假 因为bool中的滚动算术b = -1;
答案 4 :(得分:1)
bool似乎被定义为(带符号)整数类型,false为0,零为1.这解释了为什么为真&gt; false(1> 0)为真。
此外,将-1与无符号数进行比较会使-1转换为无符号,并且在您的平台上会导致整数溢出,从而导致UINT_MAX(或者类型为bool的类型)。这现在解释了为什么以下表达式是错误的:
((bool)-1) < true i. e. UINT_MAX < 1
((bool)-1) < false i. e. UINT_MAX < 0
true < false i. e. 1 < 0
答案 5 :(得分:1)
仅适用于C ++ false
&lt; true
对于C来说更难回答。我明白了
在我的stdbool.h中 typedef char _Bool; /* For C compilers without _Bool */
似乎,如果编译器支持_Bool
,它就像在C ++中一样工作并自动转换为0/1,但如果不是,它应该作为char工作,它将是b < true
,{{1如果char已签名
对于我(int)(bool)-1即使在C中也是1,所以b < false
被定义为不是char
答案 6 :(得分:1)
这是一个解释,我没有用标准检查过。 从你的实验看来,“&lt;” operator没有为布尔值定义。比较的是布尔值被转换为的无符号整数。从理论上讲,标准可能无法保证所有“真正的”布尔值都转换为相同的值。并且-1被转换为最大的unsigned int。
作为另一个实验,以下代码
#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;
}
打印1 1 1 0
所以任何非零值都是“true”。