为什么默认情况下语言不会在整数溢出时引发错误? [英] Why don't languages raise errors on integer overflow by default?

查看:28
本文介绍了为什么默认情况下语言不会在整数溢出时引发错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在几种现代编程语言(包括 C++、Java 和 C#)中,该语言允许整数溢出 在运行时发生而不会引发任何类型的错误条件.

In several modern programming languages (including C++, Java, and C#), the language allows integer overflow to occur at runtime without raising any kind of error condition.

例如,考虑这个(人为的)C# 方法,它没有考虑上溢/下溢的可能性.(为简洁起见,该方法也不处理指定列表为空引用的情况.)

For example, consider this (contrived) C# method, which does not account for the possibility of overflow/underflow. (For brevity, the method also doesn't handle the case where the specified list is a null reference.)

//Returns the sum of the values in the specified list.
private static int sumList(List<int> list)
{
    int sum = 0;
    foreach (int listItem in list)
    {
        sum += listItem;
    }
    return sum;
}

如果这个方法调用如下:

If this method is called as follows:

List<int> list = new List<int>();
list.Add(2000000000);
list.Add(2000000000);
int sum = sumList(list);

sumList()方法会发生溢出(因为C#中的int类型是32位有符号整数,而list 超出了最大 32 位有符号整数的值).sum 变量的值为 -294967296(不是 4000000000);这很可能不是 sumList 方法的(假设的)开发者想要的.

An overflow will occur in the sumList() method (because the int type in C# is a 32-bit signed integer, and the sum of the values in the list exceeds the value of the maximum 32-bit signed integer). The sum variable will have a value of -294967296 (not a value of 4000000000); this most likely is not what the (hypothetical) developer of the sumList method intended.

显然,开发人员可以使用各种技术来避免整数溢出的可能性,例如使用像 Java 的 BigInteger,或 checked 关键字和 /checked C# 中的编译器开关.

Obviously, there are various techniques that can be used by developers to avoid the possibility of integer overflow, such as using a type like Java's BigInteger, or the checked keyword and /checked compiler switch in C#.

但是,我感兴趣的问题是,为什么这些语言被设计为默认情况下首先允许发生整数溢出,而不是例如在运行时执行操作时引发异常导致溢出.如果开发人员在编写执行可能导致溢出的算术运算的代码时忽略了溢出的可能性,这种行为似乎有助于避免错误.(这些语言可能包含类似unchecked"关键字的东西,它可以指定一个允许发生整数溢出而不引发异常的块,在开发人员明确意图该行为的情况下;C# 实际上 确实有这个.)

However, the question that I'm interested in is why these languages were designed to by default allow integer overflows to happen in the first place, instead of, for example, raising an exception when an operation is performed at runtime that would result in an overflow. It seems like such behavior would help avoid bugs in cases where a developer neglects to account for the possibility of overflow when writing code that performs an arithmetic operation that could result in overflow. (These languages could have included something like an "unchecked" keyword that could designate a block where integer overflow is permitted to occur without an exception being raised, in those cases where that behavior is explicitly intended by the developer; C# actually does have this.)

答案是否简单地归结为性能 - 语言设计者不希望他们各自的语言默认具有慢"算术整数运算,运行时需要做额外的工作来检查是否发生溢出,每个适用的算术运算——在发生意外溢出的情况下,这种性能考虑超过了避免静默"失败的价值?

Does the answer simply boil down to performance -- the language designers didn't want their respective languages to default to having "slow" arithmetic integer operations where the runtime would need to do extra work to check whether an overflow occurred, on every applicable arithmetic operation -- and this performance consideration outweighed the value of avoiding "silent" failures in the case that an inadvertent overflow occurs?

除了性能方面的考虑之外,做出这种语言设计决策还有其他原因吗?

Are there other reasons for this language design decision as well, other than performance considerations?

推荐答案

在 C# 中,这是一个性能问题.具体来说,就是开箱即用的基准测试.

In C#, it was a question of performance. Specifically, out-of-box benchmarking.

当 C# 刚出现时,微软希望很多 C++ 开发人员会改用它.他们知道许多 C++ 人认为 C++ 速度很快,尤其是比那些在自动内存管理等上浪费"时间的语言更快.

When C# was new, Microsoft was hoping a lot of C++ developers would switch to it. They knew that many C++ folks thought of C++ as being fast, especially faster than languages that "wasted" time on automatic memory management and the like.

潜在的采用者和杂志评论者都可能获得新 C# 的副本,安装它,构建一个在现实世界中没人会编写的微不足道的应用程序,在一个紧密的循环中运行它,并测量它的运行时间拿.然后他们会为他们的公司做出决定或根据该结果发表文章.

Both potential adopters and magazine reviewers are likely to get a copy of the new C#, install it, build a trivial app that no one would ever write in the real world, run it in a tight loop, and measure how long it took. Then they'd make a decision for their company or publish an article based on that result.

他们的测试表明 C# 比本地编译的 C++ 慢,这一事实会让人们很快放弃 C#.您的 C# 应用程序将自动捕获上溢/下溢这一事实是他们可能会错过的事情.所以,它默认是关闭的.

The fact that their test showed C# to be slower than natively compiled C++ is the kind of thing that would turn people off C# quickly. The fact that your C# app is going to catch overflow/underflow automatically is the kind of thing that they might miss. So, it's off by default.

我认为很明显 99% 的时间我们都希望/checked 处于打开状态.这是一个不幸的妥协.

I think it's obvious that 99% of the time we want /checked to be on. It's an unfortunate compromise.

这篇关于为什么默认情况下语言不会在整数溢出时引发错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆