If I pass Int32.MinValue and -1 into the Divide()
method, I get a System.OverflowException
despite the block happening in an unchecked
block.
private static int Divide(int n, int d)
{
return unchecked (n / d);
}
This is surprising to me - unless I've read the documentation for checked / unchecked incorrectly, I'd expect it to just give me an overflowed output (since Int32.MinValue / -1 = 2^31 = Int32.MaxValue + 1, I was expecting an overflow to a value of Int32.MinValue). Instead it threw an OverflowException
.
Here's a DotNetFiddle showing the issue.
The unchecked keyword prevents overflow-checking when doing integer arithmetics. It may be used as an operator on a single expression or as a statement on a whole block of code.
C# statements can execute in either checked or unchecked context. In a checked context, arithmetic overflow raises an exception. In an unchecked context, arithmetic overflow is ignored and the result is truncated by discarding any high-order bits that don't fit in the destination type.
An OverflowException is thrown at run time under the following conditions: An arithmetic operation produces a result that is outside the range of the data type returned by the operation.
You can execute statements in C# in checked or unchecked context. In checked, the exception is raised by arithmetic overflow, whereas in unchecked context, arithmetic overflow is ignored.
An OverflowException is only thrown in a checked context. It alerts you to an integer overflow: a situation where the number becomes too large to be represented in the bytes. Exception Example. Let's look at this simple program.
For the arithmetic, casting, or conversion operation to throw an OverflowException, the operation must occur in a checked context. By default, arithmetic operations and overflows in Visual Basic are checked; in C# and F#, they are not.
} The checked and unchecked statements and operators only affect the overflow-checking context for those operations that are textually inside the statement block or operator's parentheses, as the following example shows:
It alerts you to an integer overflow: a situation where the number becomes too large to be represented in the bytes. Exception Example. Let's look at this simple program.
From the C# draft specification on integer division:
If the left operand is the smallest representable
int
orlong
value and the right operand is-1
, an overflow occurs. In achecked
context, this causes aSystem.ArithmeticException
(or a subclass thereof) to be thrown. In anunchecked
context, it is implementation-defined as to whether aSystem.ArithmeticException
(or a subclass thereof) is thrown or the overflow goes unreported with the resulting value being that of the left operand.
I'm not sure where Microsoft lists its choices for implementation-defined behavior, but apparently they chose the first option here.
This and other implementation-defined or undefined behavior is listed in Annex B of ECMA-334. The draft specification above is updated more recently, but it seems to lack this annex.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With