从选中(),可能的编译器故障而怪异的结果? [英] Weird result from unchecked(), possible compiler bug?

查看:172
本文介绍了从选中(),可能的编译器故障而怪异的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码段的值等于零:

  INT结果=选中((INT)double.MaxValue); 



然而,如果你这样做:



<$ $ p p> 双X = double.MaxValue
INT结果=(int)的X;



的结果是(将你甚至猜想这?) int.MinValue 。单单这一事实就足以怪异[参见下文],但我的印象是,选中是为了强制编译成发光假装不代码知道转换会绝对不能和/或一些溢出的情况。换句话说,它应该给相同的结果时,编译器不涉及价值观的知识(假设它是与编译检查算术溢出禁用)



那么,这是怎么回事吗?是我的的理解选中错了?



时的结果错误之一,按照C#/。 ?NET标准






编辑: int.MinValue 解释很轻松地: cvttsd2si 给0x80000000的时候就不会有溢出,但异常被屏蔽。这是由JIT编译器使用的指令时,可以在拆卸窗口可以看到。不解决虽然该问题的任何部分






根据ECMA 334(C#2规格),在选中关键字要经常截断,因此结果应该是零在这两种情况下:

  INT RESULT1 =选中((INT)double.MaxValue); 
双X = double.MaxValue;
INT结果2 =选中((int)的X);



但它不是,第二个给 int.MinValue 。这仍然气味像编译器故障而给我。


解决方案

太好了,我发现了它。规范内部深埋,还有以下内容:




在unchecked上下文中,转换总是会成功,并且进行如下



•的值向零舍入到最接近的整数值。如果该积分值是所述目标类型的范围内,则该值是转换的结果。



•的否则,转换的结果是目标类型的一个未确定的值。




所以这是它。其结果是不确定的。一切顺利。


The following snippet evaluates to zero:

int result = unchecked((int)double.MaxValue);

Whereas, if you do this:

double x = double.MaxValue
int result = (int)x;

The result is (would you even guess this?) int.MinValue. That fact alone is weird enough[see below], but I was under the impression that unchecked was meant to force the compiler into emitting code that pretends not to know that a conversion will definitely fail and/or some overflow happens. In other words, it should give the same result as when the compiler has no knowledge of the values involved (assuming it is compiled with "Check for arithmetic overflow" disabled)

So, what's going on here? Is my understanding of unchecked wrong?

Is one of the results "wrong", as per the C#/.NET standard?


edit: the int.MinValue is explained easily enough: cvttsd2si gives 0x80000000 when there would have been overflow but the exception is masked. That's the instruction used by the JIT compiler, as can be seen in the disassembly window. That doesn't solve any part of the issue though.


According to ECMA 334 (C# 2 spec), the unchecked keyword should always truncate and therefore the result should be zero in both of these cases:

int result1 = unchecked((int)double.MaxValue);
double x = double.MaxValue;
int result2 = unchecked((int)x);

But it isn't, the second one gives int.MinValue. This still smells like compiler bug to me.

解决方案

Great, I found it. Buried deep inside the spec, there is a the following:

In an unchecked context, the conversion always succeeds, and proceeds as follows.

• The value is rounded towards zero to the nearest integral value. If this integral value is within the range of the destination type, then this value is the result of the conversion.

Otherwise, the result of the conversion is an unspecified value of the destination type.

So that's it. The result is undefined. Everything goes.

这篇关于从选中(),可能的编译器故障而怪异的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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