20

在 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++ 代码,GCC 4.6.3-ubuntu5 编译为 C 代码,G++ 4.6.3-1ubuntu5 编译为 C++ 代码,你得到的只是

false < true

也就是说,以下不等式都是false

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

以下是true

false < true
4

7 回答 7

20

在 C++ 中(我怀疑在 C 中也是如此),bools 比较就像 falsewere0truewere 一样1。如果类型是,则和bool以外的值都不可能。truefalse

与其他数字类型比较bool时,它将转换为int,再次false转换为0true转换为1

编辑: C++ 和stdbool.hC99 中的布尔值都强制为 0(假)或 1(真)——bool b = -1;将 的值设置b为 1。因为1 < 11 < 0都是假的,所以问题中的不等式是正确的。

编辑:(詹姆斯)除了上面的编辑不是真的正确,至少对于C++。Abool的值不是 0 或 1,它的值是falseor true。只有当它被提升到时int,转换才会创建 和 的01

bool正如康拉德所指出的,价值观没有可比性。比较运算符会发生“通常的算术转换”,这意味着两个操作数上的整数提升,这意味着 bool转换为int(如charor short... 或枚举)。

所有这些都是相当技术性的。在实践中,您可以记住 false< true,或者您可以考虑false为 0 和true1,以最适合您的为准。唯一要记住的重要事情是 abool可以没有其他值。

(有趣的是,我不认为 a 的位模式bool是由标准强加的。实现可以使用位模式 0x550xAA例如,只要所有到整数类型的转换都给出 0 和 1,转换为bool总是给出适当的值等。包括静态变量的零初始化。)

最后一点:bool b = -1;设置b-1 != 0( 是 true, not 1,但当然会在任何数字上下文中true转换为。1

于 2012-08-14T12:04:11.780 回答
5

这很有意义。整数类型 => bool 转换是有效的b = i != 0。为了进行<比较,它通过规则 false=>0 和 true=>1 将 bool 提升为 int。在您的第一种情况下-1,将等于 true,并且两者都将提升为 1,因此它是错误的。显然,对于第二种和第三种情况,1 永远不会小于 0,而0 < 1在最后一种情况下。

于 2012-08-14T12:04:04.193 回答
2

对于 C++,只需false<true

因为 C 更难回答。我懂了

typedef char _Bool; /* For C compilers without _Bool */ 在我的 stdbool.h

似乎,如果编译器支持,它就像在 C++ 中一样工作并自动转换为 0/1,但如果不是,它应该作为 char 工作,如果 char 被签名_Bool,它将是b < trueb < false

对我来说 (int)(bool) -1 即使在 C 中也是 1,所以bool定义为非字符

于 2012-08-14T12:04:17.483 回答
2

布尔值按false小于的顺序排列true。根据标准, abool只能包含两个值:truefalse,因此转换(bool)-1应该已经产生true(因为转换为 bool 时所有非 0 值都是true)。这就是 clang 和 g++-4.7 中的行为。

实际比较(我相信)是在提升int之后进行的bool,您测试的编译器似乎避免了通过 bool 进行转换的中间步骤,而只是提升了实际bool值。

于 2012-08-14T12:04:49.417 回答
2

运算符 > 和 < 基于此:

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

这个错误: (bool)-1 < true (bool)-1 < false 因为 bool b = -1 中的滚动算术;

于 2012-08-14T12:02:44.663 回答
2

bool 似乎被定义为(有符号)整数类型,false 为 0,0 为 1。这解释了为什么 true > false (1 > 0) 为 true。

此外,将 -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
于 2012-08-14T12:03:04.460 回答
1

这是一个解释,虽然我没有检查过标准。从您的实验看来,“<”运算符似乎没有为布尔值定义。比较的是布尔值转换为的无符号整数。从理论上讲,该标准可能无法保证所有“真实”布尔值都转换为相同的值。并且 -1 被转换为最大的无符号整数。

作为另一个实验,下面的代码

#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

所以任何非零值都是“真”。

于 2012-08-14T12:12:45.803 回答