【问题标题】:arithmetic exception in C#C#中的算术异常
【发布时间】:2010-07-16 16:18:42
【问题描述】:

为什么在 C# 中 Example A 是有效的、可编译的并且只会包装而示例 B 不会编译?

一个

int val = 0;
val = val + Int32.MaxValue +2;

int val = Int32.MaxValue;
val++;

B

int val = 0;
val = 2147483647 + 1;

int val = 0;
int val = Int32.MaxValue + 1;

我知道默认情况下不会检查算术异常,除非您在配置中使用检查的方法、块或属性明确这样做。我的问题更多地与编译器有关,然后是算术异常是如何发生的。

【问题讨论】:

  • 我认为您在发布问题时错过了一些东西。 “我的问题更多地涉及________”之后是什么?

标签: c# integer-overflow


【解决方案1】:

您的 B 示例在编译时为 constant-folded,向编译器表明它保证会溢出。

由于您的 A 示例使用变量,因此无法(完全)对表达式进行常量折叠,因此编译器无法保证这些值会导致溢出。

比如……

int val = 0;
// some other thread changes `val` to -5...
val = val + Int32.MaxValue +2; // no overflow

但是,如果您知道 val 不会改变,并将 0 分配给 const int

const int startval = 0;
int val = startval + Int32.MaxValue + 2;

您可以返回编译时溢出检查,因为该值可以完全确定,因此可以进行常量折叠。

【讨论】:

    【解决方案2】:

    我知道默认情况下不会检查算术异常,除非您在配置中使用检查的方法、块或属性明确这样做

    你不知道因为那个陈述是不正确的。事实上,您知道这是不正确的,因为您提供了一个案例,证明您的陈述是错误的!

    请参阅 C# 规范的第 7.6.12 节,为方便起见,我在此复制其中的一部分:

    对于未被任何已检查或未检查的运算符或语句包围的非常量表达式(在运行时计算的表达式),默认溢出检查上下文是未检查的,除非外部因素(例如编译器切换和执行环境配置) ) 要求检查评估。

    对于常量表达式(可以在编译时完全计算的表达式),总是检查默认的溢出检查上下文。除非将常量表达式显式放置在未经检查的上下文中,否则在表达式的编译时求值期间发生的溢出总是会导致编译时错误。

    查看规范了解更多详情。

    【讨论】:

    • 足够公平,该语句应该说“在运行时”
    【解决方案3】:

    它只是与编译时检查的限制有关。某些事情只能在运行时知道。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-29
      • 2014-12-16
      • 2019-02-25
      • 2019-04-08
      • 2018-04-22
      • 2023-04-03
      • 1970-01-01
      • 2023-03-23
      相关资源
      最近更新 更多