Mar*_*ner 46 c# unchecked checked overflowexception
int y = -2147483648;
int z = unchecked(y / -1);
Run Code Online (Sandbox Code Playgroud)
第二行引起了OverflowException
.不应该unchecked
阻止这个?
例如:
int y = -2147483648;
int z = unchecked(y * 2);
Run Code Online (Sandbox Code Playgroud)
不会导致例外.
Ser*_*rvy 33
C#4规范的第7.72节(分部运营商)声明:
如果左操作数是最小的可表示的int或long值而右操作数是-1,则发生溢出.在检查的背景下,[...].在未经检查的上下文中,它是实现定义的,是否抛出System.ArithmeticException(或其子类)或溢出未报告,结果值是左操作数的值.
因此,在未经检查的上下文中抛出异常这一事实实际上并不是一个错误,因为该行为是实现定义的.
Han*_*ant 32
这不是C#编译器或抖动可以控制的例外.它特定于Intel/AMD处理器,当IDIV指令失败时,CPU会生成#DE陷阱(Divide Error).操作系统处理处理器陷阱并使用STATUS_INTEGER_OVERFLOW异常将其反射回进程.CLR尽职尽责地将其转换为匹配的托管异常.
英特尔处理器手册并非完全是有关它的信息的金矿:
非整数结果被截断(切断)为0.余数总是小于除数.溢出用#DE(除错误)异常表示,而不是CF标志.
在英语中:签名除法的结果是+2147483648,在int中不可表示,因为它是Int32.MaxValue + 1.否则,处理器表示负值的方式不可避免的副作用,它使用二进制补码编码.它产生一个代表0的值,留下奇数个其他可能的编码来表示负值和正值.负值还有一个.-Int32.MinValue
除了处理器没有捕获NEG指令并且只产生垃圾结果之外,它的溢出程度相同.
C#语言当然不是唯一遇到此问题的语言.C#语言规范通过注意特殊行为使其成为实现定义的行为(第7.8.2节).没有其他合理的事情可以用它做,生成处理异常的代码肯定被认为太不实用,产生不可忽视的慢代码.不是C#方式.
C和C++语言通过使其成为未定义的行为来规范赌注.这可能真的变得丑陋,就像使用gcc或g ++编译器编译的程序一样,通常使用MinGW工具链.其中对SEH的运行时支持不完善,它吞下异常并允许处理器重新启动除法指令.该程序挂起,在处理器不断生成#DE陷阱的情况下烧掉100%核心.将分裂转变为传奇的Halt和Catch Fire指令 :)
Mar*_*far 10
根据C#语言规范5.0的第7.8.2节,我们有以下情况:
7.8.2除法运算符
对于x/y形式的运算,应用二元运算符重载决策(第7.3.4节)来选择特定的运算符实现.操作数将转换为所选运算符的参数类型,结果的类型是运算符的返回类型.下面列出了预定义的除法运算符.运算符都计算x和y的商.
- 整数除法:
int operator /(int x, int y);
uint operator /(uint x, uint y);
long operator /(long x, long y);
ulong operator /(ulong x, ulong y);
如果右操作数的值为零,System.DivideByZeroException
则抛出a.该部门将结果舍入为零.因此,结果的绝对值是小于或等于两个操作数的商的绝对值的最大可能整数.当两个操作数具有相同符号时,结果为零或正,当两个操作数具有相反符号时,结果为零或负.如果左操作数是最小的可表示的int或long值而右操作数是-1,则发生溢出.在检查的上下文中,这会导致System.ArithmeticException
抛出(或其子类).在未经检查的上下文中,它是实现定义的,是否System.ArithmeticException
抛出(或其子类)或溢出未报告,结果值是左操作数的值.
归档时间: |
|
查看次数: |
2116 次 |
最近记录: |