来自unchecked()的奇怪结果,可能的编译器错误?

har*_*old 9 c# casting unchecked

以下代码段评估为零:

int result = unchecked((int)double.MaxValue);
Run Code Online (Sandbox Code Playgroud)

然而,如果你这样做:

double x = double.MaxValue
int result = (int)x;
Run Code Online (Sandbox Code Playgroud)

结果是(你会猜到这个吗?)int.MinValue.仅这个事实就足够了[见下文],但我的印象unchecked是强迫编译器发出代码,假装不知道转换肯定会失败和/或发生某些溢出.换句话说,它应该给出与编译器不知道所涉及的值时相同的结果(假设它是在禁用"检查算术溢出"的情况下编译的)

那么,这里发生了什么?我对unchecked错误的理解是什么?

根据C#/ .NET标准,其中一个结果是"错误的"吗?


编辑:int.MinValue很容易解释:cvttsd2si当溢出但异常被屏蔽时给出0x80000000.这是JIT编译器使用的指令,如反汇编窗口中所示.但这并不能解决问题的任何部分.


根据ECMA 334(C#2规范),unchecked关键字应始终截断,因此在这两种情况下结果应为零:

int result1 = unchecked((int)double.MaxValue);
double x = double.MaxValue;
int result2 = unchecked((int)x);
Run Code Online (Sandbox Code Playgroud)

但它不是,第二个给出int.MinValue.这对我来说仍然像编译器错误.

har*_*old 4

太好了,我找到了。在规范的深处,有以下内容:

\n
\n

在未经检查的上下文中,转换始终会成功,并按如下方式进行。

\n

\xe2\x80\xa2 该值向零舍入到最接近的整数值。如果该整数值在目标类型的范围内,则该值就是转换的结果。

\n

\xe2\x80\xa2否则,转换结果是目标类型的未指定值。

\n
\n

就是这样了。结果是未定义的。一切顺利。

\n