【发布时间】:2010-09-11 08:17:23
【问题描述】:
在几种现代编程语言(包括 C++、Java 和 C#)中,该语言允许 integer overflow 在运行时发生,而不会引发任何类型的错误条件。
例如,考虑这个(人为的)C# 方法,它没有考虑上溢/下溢的可能性。 (为简洁起见,该方法也不处理指定列表为空引用的情况。)
//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;
}
如果这个方法调用如下:
List<int> list = new List<int>();
list.Add(2000000000);
list.Add(2000000000);
int sum = sumList(list);
sumList()方法会发生溢出(因为C#中int类型是32位有符号整数,列表中的值之和超过了最大32位有符号整数的值)。 sum 变量的值为 -294967296(不是 4000000000);这很可能不是 sumList 方法的(假设的)开发者想要的。
显然,开发人员可以使用多种技术来避免整数溢出的可能性,例如使用 Java 的 BigInteger 之类的类型,或者 C# 中的 checked 关键字和 /checked 编译器开关。
但是,我感兴趣的问题是,为什么这些语言被设计为默认情况下首先允许发生整数溢出,而不是例如在运行时执行操作时引发异常导致溢出。如果开发人员在编写执行可能导致溢出的算术运算的代码时忽略了溢出的可能性,这种行为似乎有助于避免错误。 (这些语言可能包含类似“unchecked”关键字的东西,它可以指定一个允许发生整数溢出而不引发异常的块,在开发人员明确表示该行为的情况下;C# 实际上是does have this。 )
答案是否简单归结为性能 - 语言设计者不希望他们各自的语言默认具有“慢”算术整数运算,运行时需要做额外的工作来检查是否发生溢出,on每个适用的算术运算——在发生意外溢出的情况下,这种性能考虑超过了避免“静默”失败的价值?
除了性能方面的考虑之外,做出这种语言设计决策还有其他原因吗?
【问题讨论】:
标签: language-agnostic integer language-design integer-overflow