public void Foo(double d){
// when called below, d == 2^32-1
...
}
public void Bar(){
uint ui = 1;
Foo( 0 - ui );
}
我希望0和ui在这里被提升为签名多头。
是的,使用0字面值,在编译时可以知道转换为uint是安全的,
但我想这一切似乎都错了。至少应该发出警告。
谢谢!
语言规范是否涵盖了这种半模糊的情况?
答案 0 :(得分:7)
为什么会将任何内容提升为long
?规范(第7.8.5节)列出了四个整数减法运算符:
int operator-(int x, int y);
uint operator-(uint x, uint y);
long operator-(long x, long y);
ulong operator-(ulong x, ulong y);
鉴于常量值0
可隐式转换为uint
,但uint
值ui
不可隐式转换为{{ 1}},根据7.3.4节中描述的二元运算符重载决策步骤选择第二个运算符。
(您是否有可能不知道从int
到0
的隐式常量表达式转换,这是令人困惑的部分?有关详细信息,请参阅C#4规范的第6.1.9节。 )
根据第7.3.4节(后面引用的是7.3.5和7.5.3)略微曲折,但我相信它定义明确,并且一点都不含糊。
如果是困扰你的溢出,那么这个也会失败吗?
uint
如果没有,那么真正的区别是什么?
答案 1 :(得分:0)
int
被强制转换为uint
以从0执行减法(由编译器隐式解释为uint
)。请注意,int
到uint
是隐式转换,因此没有警告。您的代码没有任何问题......除了uint
不是CLS编译。您可以阅读here的原因。关于MSDN
答案 2 :(得分:0)
在已检查的上下文中,如果差异超出结果类型的范围,则抛出System.OverflowException。在未经检查的上下文中,不会报告溢出,并且会丢弃结果类型范围之外的任何重要高位。
http://msdn.microsoft.com/en-us/library/aa691376(v=vs.71).aspx
从技术上讲,执行以下操作:
double d = checked(0-ui);
将导致抛出System.OverflowException
,这可能是您所期望的,但根据规范,因为未检查溢出不会报告。