C# 0(减号)uint = 无符号结果
本文关键字:无符号 结果 uint 减号 | 更新日期: 2023-09-27 18:26:35
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 是安全的,
但我想这一切似乎都是错误的。 至少应该发出警告。
谢谢!
语言规范是否涵盖了这样的半歧义情况?
为什么任何东西都会被提升为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
不能隐式转换为int
,第二个运算符是根据 7.3.4 节中描述的二元运算符重载解析步骤选择的。
(您是否可能不知道从0
到uint
的隐式常量表达式转换,这是令人困惑的部分?有关详细信息,请参阅 C# 4 规范的第 6.1.9 节。
遵循第 7.3.4 节(然后指的是 7.3.5 和 7.5.3(有点曲折,但我相信它的定义很明确,一点也不模棱两可。
如果是溢出困扰您,会期望这也失败吗?
int x = 10;
int y = int.MaxValue - 5;
int z = x + y;
如果不是,这里到底有什么区别?
强制转换为uint
执行从 0 减法的int
(编译器隐式解释为 uint
(。请注意,int
to uint
是隐式转换,因此没有警告。你的代码没有错...除了uint
不是 CLS 编译的。你可以在这里阅读原因。有关 MSDN 上的 CLS 编译代码的详细信息
在已检查的上下文中,如果差异超出结果类型的范围,则会抛出 System.OverflowException。在未经检查的上下文中,不会报告溢出,并且会丢弃结果类型范围之外的任何重要高阶位。
http://msdn.microsoft.com/en-US/library/aa691376(v=vs.71(.aspx
从技术上讲,执行以下操作:
double d = checked(0-ui);
将导致抛出System.OverflowException
,这可能是您所期望的,但根据规范,由于未检查,因此不会报告溢出。