为什么C ++中的布尔类型支持++但不支持-?


29

为什么--布尔没有运算符,而布尔运算符却存在++呢?

我用C ++尝试过,不知道我的问题是否适用于另一种语言。我也很高兴知道。

我知道,我可以将运算符++与bool一起使用。它使布尔值等于true。

bool b = false;
b++;
// Now b == true.

为什么我们不能--相反地使用运算符?

bool b = true;
b--;
// Now b == false;

它不是很有用,但我很好奇。



那么历史原因。谢谢你的链接。你能写一个答案,我把它解决吗?
aloisdg说,请

单靠链接并不能提供很好的答案,也没有一种好的机制可以将tnis问题标记为另一个SE站点上的某些重复项。
Blrfl 2014年

1
因此,我们应该在meta.stackexchange.com或其他内容中打开一个主题。我认为您应该为良好的联系而获得因果报应,如果有人支持您,那么原始答案中的作者应该就因果报应。实际上,最初的问题也应有所作为。
aloisdg说恢复莫妮卡(Monica)2014年

2
@aloisdg跨站点复制是MSO 上的老问题。追踪链接的问题以获得更全面的了解。

Answers:


53

在C的过去,没有布尔类型。人们用int来存储布尔数据,并且这种方法大多数都可以使用。 零是假的,其他都是假的

这意味着如果您使用了一个int flag = 0;,后来又做了flag++该值,则该值为true。不管flag的值是什么(除非您做了很多,它将翻转并且回到零,但是让我们忽略它),这都是可行的-当flag的值为1时将其递增2仍然是真正。

有人用它无条件地将布尔值设置为true。我不确定它是否曾经成为惯用语言,但是在某些代码中确实如此。

这从来没有用过--,因为如果值不是1(可以是),则该值仍不会为false。并且如果它已经是false(0)并且您对其进行了减量运算符,那么它就不会保留为false。

在早期将代码从C迁移到C ++时,C ++中包含的C代码仍然能够工作非常重要。因此,在C ++规范(第5.2.6节(第71页))中,其内容为:

通过应用后缀++获得的值是在应用运算符之前操作数所具有的值。[注意:获得的值是原始值的副本]操作数应为可修改的左值。操作数的类型应为算术类型或指向完整对象类型的指针。记下结果后,通过将对象的值加1来修改该对象的值,除非该对象是类型bool,在这种情况下,将其设置为true。[注意:不建议使用此用法,请参阅附件D。]

postfix的操作数-与postfix ++运算符类似地递减,除了该操作数的类型不得为bool

在第5.3.2节中再次提到了这一点(对于前缀运算符-5.2.6位于后缀中)

如您所见,此方法已弃用(文档中的附件D,第709页),因此不应使用。

但这就是为什么。有时您可能会看到代码。但是不要这样做。


5
“有些人用它无条件地将布尔值设置为true。” 我们称他们为该死的傻瓜,而不是人们。
Deduplicator 2015年

@Deduplicator:也许是性能问题:将值加载到变量中可能比增加变量花费了更多的处理器周期。当然,在现代计算机上这可能无关紧要。
乔治

1
@乔治很可能。请记住,编写C是为了紧密匹配PDP-7指令集,而PDP-11还有其他调整。从这个 - “人们经常会猜测,他们的建立是为了使用由DEC PDP-11上C和Unix的第一走红提供的自动递增和自动递减地址模式这是在历史上是不可能的,因为没有PDP-。在开发B时,它的编号为11。但是PDP-7确实有一些“自动递增”存储单元,其特性是通过它们进行的间接存储引用使该单元增加了。

@Deduplicator:在将整数用于布尔值的代码中,每个变量递增的变量……无论如何……既可以充当计数器(递增多少次)又可以充当布尔值(是否已经递增或不)。
基思·汤普森


1

要了解此问题的历史意义,您必须考虑Therac-25的情况。Therac-25是一种向癌症患者提供辐射的医疗设备。它受到不良编程习惯的困扰,这导致了其不良的安全记录(造成了多次死亡)。

http://courses.cs.vt.edu/professionalism/Therac_25/Therac_1.html

(转到第3页的底部)

每次通过“设置测试”例程,都会递增上准直器位置检查的次数,这是一个称为Class3的共享变量。如果Class3不为零,则存在不一致,因此不应继续进行处理。Class3的零值表示相关参数与治疗一致,并且光束未被抑制。

...

在机器设置过程中,Set-Up Test将执行数百次,因为它会重新安排自身的时间以等待其他事件的发生。在代码中,Class3变量在每次通过设置测试时都增加一。由于Class3变量为1个字节,因此只能包含最大值255(十进制)。因此,每隔256次通过设置测试代码,该变量就会溢出并具有零值。这意味着在第256次通过设置测试时,将不会检查上部准直器,也不会检测到上部准直器故障。当操作员在Class3翻转为零的确切时刻按下“设置”按钮时,发生了过度曝光。因此未执行Chkcol,并且未设置F $ mal来指示上准直器仍处于野外照明位置。该软件会在没有目标物且没有扫描的情况下打开完整的25 MeV。产生了高度集中的电子束,该电子束被路径中的不锈钢镜散射和偏转。

该therac-25案例使用类似等价的operator++一个bool。但是,他们使用的编程语言不是C ++,数据类型不是bool。但是,与C ++中的保证不同,常规整数类型只会不断增加。他们的数据类型等于uint8_t

C ++决定operator++为习惯于这种编程的人们提供便利,但是与其增加值,不如将其设置为true为防止此类情况。

注意 operator++(bool)已弃用。

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf

C ++ 14的附件D:

D.1具有布尔操作数
的增量运算符不建议将布尔类型的操作数与++运算符一起使用(请参阅5.3.2和5.2.6)。


虽然这可以解释为什么不推荐使用它,但是并不能解释为什么它首先存在。

之所以存在,是因为有人在使用C进行编程时通过递增布尔值来设置布尔值。C++旨在简化从C的过渡,因此他们支持该bool类型。我只是想给出一个历史性的例子,说明人们何时实际以这种方式进行编程。
David Stone
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.