【问题标题】:Why doesn't this produce an overflow exception?为什么这不会产生溢出异常?
【发布时间】:2012-09-25 03:31:13
【问题描述】:

我正在使用 LinqPad 进行测试,但很惊讶以下代码没有产生异常:

ulong lSmallValue = 5;
ulong lBigValue = 10;

ulong lDifference = lSmallValue - lBigValue;

Console.WriteLine(lDifference);
Console.WriteLine((long)lDifference);

这会产生以下输出:

18446744073709551611
-5

幸运的是,我希望有这种行为,但我假设这会导致OverflowException 被抛出。

来自System.OverflowException

在以下情况下运行时会引发 OverflowException:

  • 算术运算产生的结果超出了运算返回的数据类型范围。
  • 强制转换或转换操作尝试执行缩小转换,并且源数据类型的值超出了目标数据类型的范围。

为什么lSmallValue - lBigValue操作不属于第一类?

【问题讨论】:

  • 可能超出范围; ulong 仍然有足够的 bits 来保存您的操作值(尽管它的解释与您的预期不同)。

标签: c# overflowexception


【解决方案1】:

默认情况下,CLR 不会抛出溢出异常。除非你使用“checked”关键字。

http://msdn.microsoft.com/en-us/library/74b4xzyw%28v=vs.71%29.aspx

UPD:实际上,我确实推荐 Jeffrey Richter 的“CLR via C#”——他让这些事情变得更加透明。我最喜欢的关于 CLR 和 C# 基础知识的书。

【讨论】:

  • 这实际上会导致抛出异常。谢谢,我以前从未遇到过checked 关键字。
【解决方案2】:

“对于引发溢出异常的算术、强制转换或转换操作,该操作必须发生在已检查的上下文中。”

一旦您将代码放入已检查的块中,就会立即调用 OverflowException。

ulong lSmallValue = 5;
ulong lBigValue = 10;
checked {
try {
    ulong lDifference = lSmallValue - lBigValue;
}
catch (OverflowException) {
    Console.WriteLine("Exception caught");
}}

【讨论】:

  • 这是错误的,如果我将它包装在 LinqPad 中的 try..catch 块中,仍然不会引发异常。
  • "Checked" 在这种情况下与 try/catch 无关。有一个checked { } 块iirc,它打开溢出检查。
  • 我不认为这是一个正确的答案 - try catch 在那里没有任何意义。您需要使用“cehcked”关键字。看我的回复较低
  • -1 这是错误的。检查的上下文与 try/catch 无关,与在 checked 块内运行有关。 unchecked 上下文是默认值。
  • 当该代码位于 try..catch 块中时,我没有收到任何异常。
猜你喜欢
  • 1970-01-01
  • 2014-07-11
  • 1970-01-01
  • 2011-01-13
  • 2018-07-10
  • 1970-01-01
  • 2014-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多