Casting int to bool in C/C++
我知道在C和C ++中,将布尔值转换为int,(int)true == 1和(int)false == 0时。 我想知道反向铸造...
在下面的代码中,以下所有断言在使用Visual Studio 2013和KeilμVision5编译的.c文件中对我而言都是正确的。请注意(bool)2 == true。
对于将非零,非一整数转换为布尔值,C和C ++标准怎么说? 是否指定了此行为? 请包括引文。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include <stdbool.h>
#include
void TestBoolCast(void)
{
int i0 = 0, i1 = 1, i2 = 2;
assert((bool)i0 == false);
assert((bool)i1 == true);
assert((bool)i2 == true);
assert(!!i0 == false);
assert(!!i1 == true);
assert(!!i2 == true);
} |
我不能为任何C ++编译器都假设(bool)true ==(int)1吗?
反向投放(int-> bool)。
那里没有讨论非零,非一的值。
-
所有非零整数应强制转换为true。我没有规格,所以我不发布答案。
-
在C / C ++中,!0为true,0为false。因此,2确实是正确的。 (2!= 0)==是。
-
@SergeyK。你真的读过这个问题吗?
-
使用(n!= 0)代替(bool)n总是安全的
-
我认为这种行为始于K&R C,并一直保持着
-
只是为了添加Microsoft在某些方面使用-1表示真实
-
@SergeyK。,如果您是提出欺骗建议的人,您可以删除该建议,还是引用那里回答我问题的部分(如果我不知怎么的话)?
-
@QuinnRoundy:C99引入了bool(实际上是通过使用stdbool.h来实现的,该映射将其映射到内置名称_Bool(等))以与C ++兼容。K&R甚至没有布尔类型,但是使用int。
-
@NathanOliver:那将是非标准的(惊喜,惊喜)。
-
@Olaf(在MSFT的世界中为True ==-1)在C和C ++的世界中,这是非标准的。但是,这个想法对我来说很有趣。 QBASIC(对于DOS)中的Not关键字是按位NOT运算符。实际上,现代VB.NET中的x And y也等同于C中的x & y。所有传统布尔运算符在该语言中都有按位行为。有了这些信息以及~0 == -1在二进制补码系统上的事实,Im丝毫不惊讶那里出现True==-1;就像在C中使用#define FALSE 0后跟#define TRUE ~(FALSE)。
-
@ChronoKitsune:" MSFT"?我可以添加Python,Modula,Pascal等,但这不会导致太大的影响吗?而且,是的,大多数BASIC方言(Apple-II,Amstrad等使用-1表示" true")。造成时间浪费的一个原因:大多数CPU具有/已具有Not(求逆)指令,与xor #1相比,该指令节省了一个操作数来求反。那时,Memroy很珍贵。 (免责声明,那当然不是全部)。
基本类型(1)(2)的0值映射到false。
其他值映射到true。
该约定是在原始C中通过其流控制语句建立的; C当时没有布尔类型。
假定作为函数返回值的false表示失败是一个常见错误。但是特别是从main到false表示成功。我已经看过很多次做错了,包括在Windows的D语言启动代码中(当您遇到Walter Bright和Andrei Alexandrescu之类的人弄错了,那么就很容易犯错),因此请注意当心。
对于内置类型,无需强制转换为bool,因为该转换是隐式的。但是,Visual C ++(Microsoft的C ++编译器)倾向于为此发出性能警告(!),这纯粹是一种愚蠢的警告。强制转换不足以将其关闭,但通过双重否定(即return !!x)进行的转换效果很好。可以将!!读取为转换为bool运算符的方式,与-->可以读取的内容一样多。对于那些深入了解运算符符号可读性的人。 ;-)
1)C ++ 14§4.12/ 1将零值,空指针值或空成员指针值转换为false;其他任何值都将转换为true。对于直接初始化(8.5),可以将类型std::nullptr_t的prvalue转换为类型bool的prvalue。结果值为false。
2)C99和C11§6.3.1.2/ 1将任何标量值转换为_Bool时,如果该值等于0,则结果为0;否则,结果为0。否则,结果为1。
-
我不认为main为成功返回" false"。 main返回int,而不是布尔值,并且具有不同的成功/失败约定。 (Unix系统调用使用第三个映射。)
-
您能否引用标准中确认您的第一部分的部分?
-
@ cp.engr:我想您没有标准或草案的副本。它是一个好主意,让一个,例如适用于C ++ 14的N3936(最新草案)。在其中签出时,您发现4.12指出"零值,空指针值或空成员指针值将转换为false;其他任何值都将转换为true。对于直接初始化(8.5),应使用prvalue类型为std :: nullptr_t的类型可以转换为bool类型的prvalue;结果值为false。"我希望这不是功课吗?它非常重要的在寻找那些在文档的方式,包括神圣的标准来训练?
-
@ Cheersandhth.-Alf,不,不是作业;我是一个工作专业人员。只是还不熟悉标准导航。 C与stdbool有关吗?
-
@ cp.engr:哦。我没有最新的C标准,对不起。在C99中,在6.3.1.2/1中进行了指定:"将任何标量值转换为_Bool时,如果该值等于0,则结果为0;否则,结果为1"
-
@ cp.engr:请阅读我的答案。
-
@ Cheersandhth.-Alf,感谢您的引用。 C ++ 14引用是否适用于所有旧版本的C ++? C标准报价是否适用于C89,C90?
-
@ cp.engr:关于C ++,是的。关于C,不完全的,因为其_Bool用C99引入。但是,标准化的行为是1970年代早期K&R C的行为,因此,无论引入什么类型等,标准都将确保这种行为。
-
我认为您应该修改或删除第二段-main不返回布尔值,而是返回int值。它似乎也...可能偏离主题?但是,你的第一款+引用做回答我提出的问题,那么答案接受。谢谢。 :)
-
@ cp.engr:该段很好。 main返回int是正确的。而且它根本不是题外话,不可能找到更相关的东西。大约15年前,我仍然有为那些拒绝思考的人编写代码和解释的想法。那是一场灾难。我决定停止这样做。我认为那是正确的事情。 ;-)
以下引用了C11标准(最终草案)。
6.3.1.2: When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1.
bool(对于C,由stdbool.h映射为内部名称_Bool)本身是一个无符号整数类型:
... The type _Bool and the unsigned integer types that correspond to the standard signed integer types are the standard unsigned integer types.
根据6.2.5p2:
An object declared as type _Bool is large enough to store the values 0 and 1.
AFAIK这些定义在语义上与C ++相同-内置(!)名称略有不同。对于C ++,bool,对于C,_Bool。
请注意,C不像C ++那样使用术语rvalues。但是,在C中,指针是标量,因此将指针分配给_Bool的行为与C ++中的行为相同。
-
从C ++ 03开始:"算术,枚举,指针或成员类型的指针的右值可以转换为bool类型的右值。零值,空指针值或空成员指针值将转换为false;任何其他值被转换为真"。我确定这个问题是骗人的。
-
@MichaelBurr:我同意C ++的双重含义,但可能不适用于C。我仍在C标准中寻找对应的段落。
-
关于" AFAIK,这些定义在C和C ++之间是相同的",并非完全不正确。在C ++中,bool是内置类型,而不是宏,并且没有类似_Bool的东西。
-
@ Cheersandhth.-Alf:是的,我想我已经通过" stdbool.h映射到C的内部名称_Bool"来清楚地说明这一点。它只是名称:C:_Bool(bool是映射到_Bool的宏),C ++:bool。原因是向后兼容,因为许多代码都有自己的bool别名/ #define / enum。该类型刚刚添加到标准中为时已晚。
-
我搜索了@MichaelBurr,但没有找到关于C和C ++标准所说的答案的答案。是否(bool)2 == true。如果可以找到,请在此处链接。
-
@ cp.engr:我同意您的问题不是对那些与之密切相关的问题的重复。我可能不应该有关于我的评论受骗者涉及的问题 - 遗憾的是。对我来说,是否欺骗没有关系。它与合法的回答一个合法的问题。最重要的是,您应该能够依靠直观的行为(0转换为false,非零转换为true)。
-
@Olaf,在你的答案有用的信息,并感谢特别是对链接。由于另一个答案包括对C和C ++的引用,因此我接受了那个。
-
需要注意的陷阱是某些代码库(尤其是C99之前的代码库)可能使用typedef char bool或typedef int bool而不是使用stdbool.h。
-
@ M.M:谢谢您的补充。考虑到手工制作类型的各种方式,不可能涵盖所有可能的情况。没有附加信息的C标记是指标准C,即C11(请阅读Wiki)。 18年后,该是切掉死木的时候了。使用标准库(此处为stdbool.h)后,此处定义的名称将保留,并且不得由用户代码定义。否则,代码将调用未定义的行为。
删除警告的另一种方法(至少在MS Visual Studio 2019 C ++中)是使用三元运算符并将值直接设置为true或false:
1 2
| int i = 3; // Or another value
bool b = (i ? true : false); |
或者更明确地说:
1 2
| int i = 3; // Or another value
bool b = (i == 0 ? false : true); |
-
确实如此,但很浪费,除非编译器通过将分支转换为强制转换进行优化。我想它是否更清晰是主观的。
-
值-1是否也应为真?
-
@AnnaVopureta在C ++中,true定义为1,false定义为0,但是在C中,没有true和false,只有TRUE和FALSE,它们是用户定义的值,并且由于未正式定义而可以是多个值,可以是1,255甚至是0(如果您愿意的话,虽然0很少用于FALSE)。
-
C ++ 14 4.12 / 1"零值,空指针值或空成员指针值将转换为false;任何其他值都将转换为true"。您的第二个示例是错误的,因为它将负值映射为false。
-
@AnnaVopureta是的,您是对的,我更新了答案,感谢您的通知。
-
@AnnaVopureta更新(第一次出问题了)
-
应该是:bool b =(i == 0?false:true);
-
@edwinc当然可以。谢谢,我更新了答案。