我可以为任何 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) true1 的整数值,但 if (pointer) 之类的东西如果 pointer != 0 则通过 then 部分。唯一可以假设为真的是false == 0true != 0(当转换为int 时,true 的计算结果为1 【参考方案1】:

是的。演员表是多余的。在你的表达中:

true == 1

积分提升适用,布尔值将提升为int,此提升必须产生 1。

参考:4.7 [conv.integral] / 4:如果源类型为bool...true转换为一。

【讨论】:

@Joshua:true 是语言定义的关键字。它不能由库重新定义。 #defines 不允许重新定义关键字。 @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 标准库的函数)返回的值“基本上是布尔值”,但表示为ints 通常只需要为零表示错误或非零表示正确。例如,<ctype.h> 中的 is* 函数只需要零或非零,不一定是零或一。

如果您将其转换为 bool,则零将转换为 false,非零转换为 true(如您所料)。

【讨论】:

【参考方案4】:

根据标准,您应该对这个假设放心。 C++ bool 类型有两个值 - truefalse,对应的值为 1 和 0。

需要注意的是将bool 表达式和变量与BOOL 表达式和变量混合。后者定义为FALSE = 0TRUE != 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 下吗?

使用 RegEx 去除 C++ 中的多行注释

如何使用 Boost Python 从 C++ bool 转换为 Python boolean?

混合来自不同编译器的 C++ 代码

C++笔记--bool类型(1-3)

将 numpy 指针 (dtype=np.bool) 传递给 C++