布尔到整数的转换


130

这种转换的可移植性。我可以确定两个断言都通过了吗?

int x = 4<5;
assert(x==1);

x = 4>5;
assert(x==0);

不要问为什么。我知道这很丑。谢谢。


为什么不更改第一个表达式?你可以写 assert(x!=0)。即使bool(true)将Portable转换为int(1),“ not false”断言也具有更易读的表达式。
哈珀

1
为什么不:assert( 4 < 5);assert(!( 4 > 5));
马丁纽约

4
@harper:使用比较表达式的所需值是完全合理的。
R .. GitHub停止帮助ICE,

@ R._当问题是bool到int转换是否给出合理的结果时,我不会依赖于此。当作者怀疑此要求已得到满足时,读者可能会遇到同样的问题。特别是因为x的值不是检查条件,而只是中间结果。
哈珀

3
(4 < 5) ? 1 : 0如果我真的需要将布尔值转换为0或1,我可能会写。一个好的编译器可能会产生相同的机器代码,对于人类读者来说更清楚。
ollb 2011年

Answers:


204
int x = 4<5;

完全便携。符合标准。boolint转换是隐式的!

来自C ++标准的§4.7/ 4说(整体转换

如果源类型为bool,则值false将转换为零,并且值true将转换为1


至于C,据我所知是没有bool的C.(1999年以前),所以boolint转换在C ++中才有意义。在C中,4<5int值为,在这种情况下,值为14>5 将求值为0

编辑:詹斯在评论中说,C99具有_Bool类型。bool是在stdbool.h头文件中定义的宏。true并且false也在中定义了宏stdbool.h

C99的第7.16节说:

bool扩展为_Bool。

[..] true扩展为整数常量1false 扩展为整数常量0,[..]


3
确保bool自1999年以来C 就在其中。只需使用“ stdbool.h”标头即可,并且应包含此标头。
詹斯·古斯特

1
确实,我在几个编译器上进行了检查,它似乎是可移植的。
pic11 2011年

8
不论C语言的版本和bool/ _Bool类型的可用性如何,C中的关系运算符都会产生int,而不是bool。即使在C99中,关系运算符仍会产生int
2011年

51

您同时标记了问题[C]和[C ++]。语言之间的结果将是一致的,但是每种语言的答案结构都不同。

在C语言中,您的示例与bool任何内容均无关(也适用于C99)。在C语言中,关系运算符不会产生bool结果。两者4 > 54 < 5是产生类型的结果的表达式int用值01。因此,在C中的示例中不会发生任何类型的“布尔到整数转换”。

在C ++中,关系运算符确实会产生bool结果。bool值可以转换为inttype,可以true转换为1false转换为0。这是由语言保证的。

PS C语言还具有专用的布尔类型_Bool(宏别名为bool),其积分转换规则与C ++基本相同。但是,这与您在C中的特定示例无关。再次,无论语言规范的版本如何,C中的关系运算符始终会产生int(而非bool)结果。


2
没错,K&R C中没有问题。我将问题重新标记为C99。
pic11 2011年

@ pic11:无需重新标记任何内容。它与K&R或任何其他C无关。即使bool在C99中存在关系关系运算符仍在intC99中产生,而不是bool。因此,如果您感兴趣的是关系运算符(如您的示例),则该问题仍然与无关bool
2011年

现在我懂了。关系运算符的结果隐式转换为int。在C,C99和C ++中确实如此。重新目标。
pic11 2011年

3
@ pic11:不,你不明白。在C中(包括C99),比较运算符的结果为int,而不是bool没有转换发生。
R .. GitHub停止帮助ICE,

有没有一种符合标准的方法,一种语言可以具有某种行为,bool而其行为却类似但不允许采用其地址?许多嵌入式系统都使用此类类型(通常使用identifier声明bit)。例如,在中档PIC上,if (bitVar1) bitVar2=1;将有两条指令;最佳编码if (byteVar1) byteVar2=1;至少为四个(在许多编译器上,可能为五个)。因此,此类类型可以大大提高性能。
supercat 2014年

17

C标准的6.5.8.6节说:

如果指定的关系为true,则每个运算符<(小于),>(大于),<=(小于或等于)和> =(大于或等于)应产生1,如果为0,则产生0。 false。)结果的类型为int。


感谢您的参考。由于历史原因,似乎true == 1。
pic11 2011年

2

由于int到bool的转换是隐式完成的,因此似乎没有问题。这适用于Microsoft Visual C ++,GCC和Intel C ++编译器。在C或C ++中都没有问题。


2
“在某些情况下有效”不是检查正确性的好方法,特别是对于那些工具的未指定版本。我更喜欢其他答案中的方法。他们不能保证特定的实现是正确的,但是可以保证正确的实现会做什么。
马修(Matthew)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.