为什么C#规格休假(int.MinValue / -1)实现定义的? [英] Why does the C# specification leave (int.MinValue / -1) implementation defined?

查看:258
本文介绍了为什么C#规格休假(int.MinValue / -1)实现定义的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

表达 int.Minvalue / -1 的结果实现定义的行为:

The expression int.Minvalue / -1 results in implementation defined behavior according to the C# specification:

7.8.2除法运算符

7.8.2 Division operator

如果左操作数是最小int或long值,右操作数为-1,一个$ b出现$ b溢出。在checked上下文中,这会导致
System.ArithmeticException(或其子类)被抛出。在
未选中背景下,实现定义关于是否
System.ArithmeticException(或其子类)被抛出或
溢出去与未报告,所得到的值是该
左操作数

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));

这将引发发生OverflowException 在.NET 4.5 32位,但它不必

This throws an OverflowException on .NET 4.5 32bit, but it does not have to.

为什么本说明书离开结果实现定义?下面是针对这样做的情况:

Why does the specification leave the outcome implementation-defined? Here's the case against doing that:


  1. x86的 IDIV 指令总是导致一个除了在这种情况下。

  2. 在其他平台上运行时检查可能有必要仿效这一点。但是,检查的费用相比,该部门的成本低。整数除法是极其昂贵的(15-30次)。

  3. 这将打开兼容性的风险(编写一次运行无处)。

  4. 开发者的惊喜。

  1. The x86 idiv instruction always results in an exception in this case.
  2. On other platforms a runtime check might be necessary to emulate this. But the cost of that check would be low compared to the cost of the division. Integer division is extremely expensive (15-30 cycles).
  3. This opens compatibility risks ("write once run nowhere").
  4. Developer surprise.

另外有趣的是,如果 X / Y 是一个编译时我们不断得到确实选中(int.MinValue / -1)== int.MinValue

Also interesting is the fact, that if x / y is a compiletime constant we indeed get unchecked(int.MinValue / -1) == int.MinValue:

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

这意味着 X / Y 可以有不同的语法形式不同的行为正在使用(而不是只依赖于 X 和)。这是由规范所允许,但它似乎是一个明智的选择。为什么C#这样设计?

This means that x / y can have different behaviors depending on the syntactic form being used (and not only depending on the values of x and y). This is allowed by the specification but it seems like an unwise choice. Why was C# designed like this?

一个的类似的问题,其中在规范这个确切行为被规定,但它没有(足够的)指出答案的为什么的语言设计这条路。替代的选择是不进行讨论。

A similar question points out where in the specification this exact behavior is prescribed but it does not (sufficiently) answer why the language was designed this way. Alternative choices are not discussed.

推荐答案

这是C#语言规范的大哥哥的副作用,的Ecma-335 ,通用语言基础结构规范。第三节,章3.31介绍DIV操作码做什么。该C#规格非常往往有一个规范的推迟到,很必然的。它规定,它的可能的抛出,但并不要求它。

This is a side-effect of the C# Language Specification's bigger brother, Ecma-335, the Common Language Infrastructure specification. Section III, chapter 3.31 describes what the DIV opcode does. A spec that the C# spec very often has to defer to, pretty inevitable. It specifies that it may throw but does not demand it.

另外的什么是真正的处理器做一个现实的评估。并且大家使用的是怪异的。英特尔处理器过分离奇约溢出的行为,它们被设计早在20世纪70年代的假设,每个人都将使用INTO指令。没有人做,一个故事的另一天。它不会在一个IDIV忽略溢出但是并引发#DE陷阱,不能忽略的是一声巨响。

Otherwise a realistic assessment of what real processors do. And the one that everybody uses is the weird one. Intel processors are excessively quirky about overflow behavior, they were designed back in the 1970s with the assumption that everybody would use the INTO instruction. Nobody does, a story for another day. It doesn't ignore overflow on an IDIV however and raises the #DE trap, can't ignore that loud bang.

非常艰难写上不一致的处理器行为之上的羊毛运行规范上的语言规范。小的C#团队可以做到与而是转发不精确的语言。他们已经超越了规范通过记录发生OverflowException而不是ArithmeticException的。很调皮。他们有一个偷看。

Pretty tough to write a language spec on top of a woolly runtime spec on top of inconsistent processor behavior. Little that the C# team could do with that but forward the imprecise language. They already went beyond the spec by documenting OverflowException instead of ArithmeticException. Very naughty. They had a peek.

这揭示了实践一斑。这是非常不可能是一个问题,抖动判断是否内联。和抛出非内嵌版本,期望的是,内联版本确实也是如此。没有人尚未感到失望。

A peek that revealed the practice. It is very unlikely to be a problem, the jitter decides whether or not to inline. And the non-inlined version throws, expectation is that the inlined version does as well. Nobody has been disappointed yet.

这篇关于为什么C#规格休假(int.MinValue / -1)实现定义的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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