我可以为任何 C++ 编译器假设 (bool)true == (int)1 吗?
Posted
技术标签:
【中文标题】我可以为任何 C++ 编译器假设 (bool)true == (int)1 吗?【英文标题】:Can I assume (bool)true == (int)1 for any C++ compiler? 【发布时间】:2011-02-13 01:55:32 【问题描述】:我可以为任何 C++ 编译器假设 (bool)true == (int)1
吗?
【问题讨论】:
您问题中的演员表是多余的,是否应该颠倒? 他不是说他们是演员,他是说bool t = true; int n = 1; if (t == n) ... ;
@egrunin: 嗯,但是 true 是一个 bool 而 1 是一个 int。 :)
对,我是说值的类型。
(int) true
是 1
的整数值,但 if (pointer)
之类的东西如果 pointer != 0
则通过 then 部分。唯一可以假设为真的是false == 0
和true != 0
(当转换为int
时,true
的计算结果为1
)
【参考方案1】:
是的。演员表是多余的。在你的表达中:
true == 1
积分提升适用,布尔值将提升为int
,此提升必须产生 1。
参考:4.7 [conv.integral] / 4:如果源类型为bool
...true
转换为一。
【讨论】:
@Joshua:true
是语言定义的关键字。它不能由库重新定义。 #define
s 不允许重新定义关键字。
@jalf: #define 确实允许定义系统关键字。 C 编译的预处理阶段是纯文本的,一般对关键字或 C 语法一无所知。然而,当然,重新定义语言关键字几乎总是一个坏主意。
@jalf。他们不是?请参阅gcc.gnu.org/onlinedocs/cpp/Macros.html,以及国际混淆 C 代码竞赛中的至少一个条目,该竞赛曾经问过“while
什么时候不需要一段时间?” (答案:当它需要两个参数时,因为那个条目有#defined
它到printf
。)
C99, §6.10.1/1 说:“控制条件包含的表达式应该是一个整数常量表达式,除了:它不应包含强制转换;标识符(包括在词法上与关键字相同的那些)解释如下;"虽然没有声明为直接许可,但这清楚地考虑了与关键字“词法相同”的宏的可能性。
哦,#defines 可以重新定义关键字。 C++1x 的新关键字导致太多问题,因此必须删除要求。【参考方案2】:
我发现不同的编译器在 true 时返回不同的结果。我还发现,将 bool 与 bool 而不是 int 进行比较几乎总是更好。随着程序的发展,这些整数往往会随着时间的推移而改变值,如果你假设 true 为 1,你可能会被代码中其他地方的不相关更改所困扰。
【讨论】:
这是 C++ 的错误答案,因为true
是具有已定义行为的语言关键字。如果引用TRUE
等常用定义的宏是正确的。
可能是我的经验是使用 C 编译器 - 这些年来我花了很多时间使用它们。我关于在 if 语句中直接使用数学表达式的观点仍然存在。我们有代码查看 if 中的位移是否非零,然后其他人取相同的非零值并假设它是 1 并炸毁东西。简单地转换为 true/1 就可以防止这种情况发生。
我也见过这种行为。不可否认,我最后一次看到它是在 1999 年左右。我使用的是 GCC。语言是 C。不过,我确实看到过这种行为。
发生这种情况是因为bool
存储在 1 字节中,而不是 1 位中。在一个有效的程序中,该字节只能保存值 0 或 1,但在存在 undefined behavior 的情况下,很可能会在该字节中获得除 0 或 1 之外的值。编译器不会对这种情况进行补偿,这可能会导致此答案中描述的体验。【参考方案3】:
查尔斯·贝利的回答是正确的。 C++ 标准的确切措辞是(第 4.7/4 节):“如果源类型为 bool,则值 false 将转换为 0,而值 true 将转换为 1。”
编辑:我看到他也添加了参考资料——如果我不分心并忘记的话,我很快就会删除它......
Edit2:再一次,可能值得注意的是,虽然布尔值本身总是转换为零或一,但许多函数(尤其是来自 C 标准库的函数)返回的值“基本上是布尔值”,但表示为int
s 通常只需要为零表示错误或非零表示正确。例如,<ctype.h>
中的 is* 函数只需要零或非零,不一定是零或一。
如果您将其转换为 bool
,则零将转换为 false,非零转换为 true(如您所料)。
【讨论】:
【参考方案4】:根据标准,您应该对这个假设放心。 C++ bool
类型有两个值 - true
和 false
,对应的值为 1 和 0。
需要注意的是将bool
表达式和变量与BOOL
表达式和变量混合。后者定义为FALSE = 0
和TRUE != FALSE
,这在实践中通常意味着任何不同于0 的值都被视为TRUE
。
如果 BOOL
的值不是 0 或 1,许多现代编译器实际上会对任何隐式尝试从 BOOL
转换为 bool
的代码发出警告。
【讨论】:
【参考方案5】:如果我写代码:
int a=true;
cout<<a;
输出将是:
1
所以是的,你可以假设(bool)true==(int)1
【讨论】:
以上是关于我可以为任何 C++ 编译器假设 (bool)true == (int)1 吗?的主要内容,如果未能解决你的问题,请参考以下文章
xcode 4.4.1 c++11 头文件仍归档在 tr1 下吗?