gpt4 book ai didi

c# - 为什么 C# 规范保留 (int.MinValue/-1) 实现定义?

转载 作者:IT王子 更新时间:2023-10-29 04:25:03 25 4
gpt4 key购买 nike

根据 C# 规范,表达式 int.Minvalue/-1 导致实现定义的行为:

7.8.2 Division operator

If the left operand is the smallest representable int or long value and the right operand is –1, an overflow occurs. In a checked context, this causes a System.ArithmeticException (or a subclass thereof) to be thrown. In an unchecked context, it is implementation-defined as to whether a System.ArithmeticException (or a subclass thereof) is thrown or the overflow goes unreported with the resulting value being that of the left operand.

测试程序:

var x = int.MinValue;
var y = -1;
Console.WriteLine(unchecked(x / y));

这会在 .NET 4.5 32 位上抛出一个 OverflowException,但这不是必须的。

为什么规范将结果保留为实现定义?以下是反对这样做的案例:

  1. 在这种情况下,x86 idiv 指令总是导致异常。
  2. 在其他平台上,可能需要运行时检查来模拟这一点。但是与部门的成本相比,该支票的成本会很低。整数除法非常昂贵(15-30 个周期)。
  3. 这会带来兼容性风险(“一次编写,无处可运行”)。
  4. 开发者惊喜。

另一个有趣的事实是,如果 x/y 是编译时常量,我们确实会得到 unchecked(int.MinValue/-1) == int.MinValue:

Console.WriteLine(unchecked(int.MinValue / -1)); //-2147483648

这意味着 x/y 可以有不同的行为,这取决于所使用的句法形式(并且不仅取决于 xy)。规范允许这样做,但这似乎是一个不明智的选择。为什么 C# 是这样设计的?

A similar question指出规范中规定了这种确切行为的位置,但它没有(充分)回答为什么语言是这样设计的。不讨论其他选择。

最佳答案

这是 C# 语言规范的大哥 Ecma-335 的副作用,公共(public)语言基础设施规范。第 III 节,第 3.31 章描述了 DIV 操作码的作用。 C# 规范经常必须遵守的规范,这是不可避免的。它指定它可能抛出但不要求抛出。

否则对真实处理器所做的事情进行现实评估。每个人都使用的那个是奇怪的。英特尔处理器对溢出行为过于古怪,它们是在 1970 年代设计的,假设每个人都会使用 INTO 指令。没有人这样做,这是另一天的故事。它不会忽略 IDIV 上的溢出,但是会引发 #DE 陷阱,不能忽略那一声巨响。

在不一致的处理器行为之上,在一个毛茸茸的运行时规范之上编写一个语言规范是非常困难的。 C# 团队对此无能为力,只能转发不精确的语言。他们已经通过记录 OverflowException 而不是 ArithmeticException 超越了规范。很调皮。他们偷看了一眼。

揭示实践的一瞥。这不太可能成为问题,抖动决定是否内联。和 non-inlined version throws,期望内联版本也是如此。还没有人失望过。

关于c# - 为什么 C# 规范保留 (int.MinValue/-1) 实现定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31775042/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com