任何 C++ 编译器都可以假设 (bool)true == (int)1 吗?

140

我可以假设在任何C++编译器上都成立(bool)true == (int)1吗?


3
你的问题中提到的演员阵容是多余的,它们应该被倒转吗? - GManNickG
12
他的意思不是要它们成为演员阵容,他指的是 bool t = true; int n = 1; if (t == n) {...} ; - egrunin
7
@egrunin说:“嗯,但是True是布尔类型,1是整型。” :) - GManNickG
1
没错,我是想说明值的类型。 - Petruza
3
(int) true 作为整数的值是 1,但是像 if (pointer) 这样的语句只有在 pointer != 0 时才会执行其中的代码块。你可以假设的唯一真值是 false == 0,而 true != 0 (当将 true 强制类型转换为整数时,其值为 1)。 - Luis Colorado
显示剩余2条评论
5个回答

160
是的,强制类型转换是多余的。在您的表达式中:
true == 1

整型提升会应用,布尔值会被提升为int类型,这个提升必须得到1。

参考资料:4.7 [conv.integral] / 4: 如果源类型是bool... true被转换成1。


9
@Joshua:true 是由该语言定义的关键字,无法被库重新定义。 #define 不允许重新定义关键字。 - jalf
26
@jalf:#define指令确实可以定义系统关键字。C编译的预处理阶段纯文本处理,对于关键字或C语法一无所知。然而,重新定义语言关键字几乎总是一个坏主意。 - Dale Hagglund
2
@jalf。他们不是吗?请参阅http://gcc.gnu.org/onlinedocs/cpp/Macros.html,以及国际混淆C代码大赛中的至少一个条目,该比赛曾经问过“当`while`不需要花费时间时会发生什么?”(答案:当它需要两个参数时,因为那个条目已将其定义为`printf`。) - Ken Bloom
3
C99,§6.10.1/1 规定:“控制条件包含的表达式应当是一个整型常量表达式,但它不得包含强制类型转换;标识符(包括与关键字在词法上相同的标识符)将按照下面所述进行解释。” 虽然没有明确允许,但这显然考虑了可能存在与关键字“词法上相同”的宏定义。 - Jerry Coffin
3
哦,而 #define 指令允许重新定义关键字。C++1x 引入的新关键字引起了太多的问题,因此这个要求必须被移除。 - Joshua
显示剩余18条评论

19

查尔斯·贝利(Charles Bailey)的答案是正确的。C++标准的确切措辞如下(§4.7 / 4):“如果源类型是bool,则值false转换为零,值true转换为一。”

编辑:我看到他已经添加了引用--如果我没有分心而忘记的话,我很快就会删除这个...

编辑2:然而,值得注意的是,虽然布尔值本身始终转换为零或一,但许多函数(尤其是来自C标准库的函数)返回的值是“基本上是布尔”的,它们被表示为int,通常只需要为零以指示false或非零以指示true。例如,在<ctype.h>中的is*函数仅需要零或非零,不必是零或一。

如果将其强制转换为bool,则零将转换为false,非零将转换为true(正如您所期望的那样)。


11

根据标准,你的假设是安全的。C++ bool 类型只有两个值——truefalse,分别对应值 1 和 0。

需要注意的是,不要混淆 bool 表达式和变量与 BOOL 表达式和变量。后者被定义为 FALSE = 0TRUE != FALSE,实际上往往意味着任何非零值都被视为 TRUE

许多现代编译器实际上会对任何隐式尝试将 BOOL 值从非 0 或 1 的值转换为 bool 的代码发出警告。


6

我发现不同的编译器在true方面返回不同的结果。我也发现,与其将bool与int进行比较,最好将bool与bool进行比较。那些int往往随着程序的发展而改变值,如果您假设true为1,则可能会被代码中其他地方的不相关更改所影响。


4
对于 C++,这是一个不正确的答案,因为 true 是一个带有定义行为的语言关键字。如果您参考常见的宏定义(如 TRUE),那么就是正确的。 - David Thornley
1
也许是因为我的经验是使用C编译器 - 这些年来我花了很多时间在它们上面。但我所说的直接在if语句中使用数学表达式的观点依然成立。我们有一些代码,在if语句中检查一个位移是否非零,然后另一个人拿着同样的非零值并假定它是1,结果弄炸了东西。将其简单地转换为true / 1就可以防止这种情况。 - Michael Dorgan
我也曾见过这种行为。诚然,我上次看到它是在1999年左右。当时我使用的是GCC编译器,语言是C。不过,我确实见过这种行为。 - thb
1
这是因为 bool 存储在 1 字节中,而不是 1 位。在一个有效的程序中,该字节只能存储值 0 或 1,但存在**未定义行为**的情况下,可能会在该字节中存储除 0 或 1 以外的值。编译器不会对这种情况进行补偿,这可能导致本答案所描述的经验。 - rustyx

1

如果我写下以下代码:

int a=true;
cout<<a;

输出结果将是:

1

所以,是的,你可以假设 (bool)true==(int)1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接