|
51
|
| Jon Schneider Stefan · 技术社区 · 17 年前 |
|
|
1
40
在C#中,这是一个性能问题。具体来说,就是开箱即用的基准测试。 当C#是新的时候,微软希望很多C++开发人员会转而使用它。他们知道,许多C++人认为C++很快,尤其是比那些在自动内存管理等方面“浪费”时间的语言快。 潜在的采用者和杂志评论家都可能获得新C#的副本,安装它,构建一个在现实世界中没有人会编写的琐碎应用程序,在一个紧密的循环中运行它,并测量它花了多长时间。然后,他们会根据结果为公司做出决定或发表文章。 他们的测试表明C#比本机编译的C++慢,这一事实会让人们很快放弃C#。你的C#应用程序会自动捕获溢出/下溢,这是他们可能会错过的事情。所以,默认情况下它是关闭的。 我认为很明显,99%的时间我们都希望/检查是否打开。这是一个不幸的妥协。 |
|
|
2
26
我认为表现是一个很好的理由。如果你考虑一个典型程序中递增整数的每条指令,如果不是简单的加1操作,而是每次都要检查加1是否会溢出类型,那么额外周期的成本将非常严重。 |
|
3
16
您的工作假设是整数溢出总是不受欢迎的行为。 有时整数溢出是理想的行为。我见过的一个例子是将绝对航向值表示为定点数。给定一个无符号整数,0是0或360度,最大32位无符号整数(0xffffff)是360度以下的最大值。
可能还有其他可以接受溢出的情况,类似于这个例子。 |
|
|
4
8
C/C++从不强制陷阱行为。即使是显而易见的除以0也是C++中未定义的行为,而不是一种特定的陷阱。 C语言没有任何陷阱的概念,除非你计算信号。 C++有一个设计原则,除非你要求,否则它不会引入C中不存在的开销。因此,Stroustrup不想强制整数以需要任何显式检查的方式运行。 一些早期的编译器和受限硬件的轻量级实现根本不支持异常,并且通常可以通过编译器选项禁用异常。强制语言内置的例外情况将是有问题的。 即使C++检查了整数,早期99%的程序员也会因为性能提升而关闭。.. |
|
|
5
7
因为检查溢出需要时间。通常转换为单个汇编指令的每个原始数学运算都必须包括溢出检查,从而产生多个汇编指令,这可能会导致程序慢几倍。 |
|
|
6
6
这可能是99%的性能。在x86上,必须检查每个操作的溢出标志,这将对性能产生巨大影响。 另外1%将涵盖人们在混合有符号和无符号操作时进行花哨的位操作或“不精确”的情况,并希望获得溢出语义。 |
|
|
7
4
向后兼容性是一个很大的问题。使用C时,假设您对数据类型的大小给予了足够的关注,如果发生溢出/下溢,那就是您想要的。然后使用C++、C#和Java,“内置”数据类型的工作方式几乎没有变化。 |
|
|
8
0
如果整数溢出被定义为立即发出信号、抛出异常或以其他方式偏转程序执行,那么任何可能溢出的计算都需要按照指定的顺序执行。即使在整数溢出检查不会直接花费任何成本的平台上,将整数溢出精确地捕获在程序执行序列中的正确点的要求也会严重阻碍许多有用的优化。 如果一种语言规定整数溢出将设置一个锁存错误标志,限制函数内对该标志的操作如何影响其在调用代码中的值,并规定在溢出不会导致错误输出或行为的情况下不需要设置该标志,那么编译器可以生成比任何手动溢出检查程序员都更有效的代码。举个简单的例子,如果一个人在C中有一个函数,可以将两个数字相乘并返回一个结果,在溢出的情况下设置一个错误标志,那么无论调用者是否会使用结果,编译器都需要执行乘法。然而,在像我描述的规则更宽松的语言中,一个确定没有任何东西使用乘法结果的编译器可以推断溢出不会影响程序的输出,并完全跳过乘法。 从实际角度来看,大多数程序并不关心溢出发生的确切时间,因为它们需要保证不会因溢出而产生错误的结果。不幸的是,编程语言的整数溢出检测语义还没有赶上让编译器生成高效代码所必需的语义。 |
|
|
9
-4
我对为什么在运行时默认情况下不会出现错误的理解归结为希望创建具有类似ACID行为的编程语言的遗留问题。具体来说,这一原则是,你为它编写代码(或不编写代码)的任何事情,它都会做(或不做)。如果你没有编写一些错误处理程序,那么机器会因为没有错误处理程序而“假设”你真的想做你告诉它做的荒谬、容易崩溃的事情。 (ACID参考: http://en.wikipedia.org/wiki/ACID ) |