user702769
user702769

Reputation: 2445

Getting an overflow error within unchecked statement

byte b;
int i;

unchecked
{
    b = 255 + 255; //overflows
    i = 100 + int.MaxValue+100; // works

}

1) Is the reason why b expression (b = 255 + 255;) causes an overflow error due to being affected by two conflicting rules, where first rule R1 states:

A constant-expression (§7.19) of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant-expression is within the range of the destination type.

while second rule R2 states that within unchecked context overflow is allowed.

And in the case of b expression, R1 takes precedence over R2, and thus since constant expression 255+ 255 is not within the range of destination type ( which is byte ), R1 causes an error, even though R2 permits an overflow?

2)

a) Here's my reasoning as to why i expression (i = 100 + int.MaxValue+100;) doesn't cause an error:

1 - When compiler starts computing i expression, it doesn't try to promote values 100 and int.MaxValue to type long before performing the addition ( thus during the computation process the two values are still of type int )

2 - the addition does cause an overflow, but since this happens within unchecked context, no error is thrown

3 - Since the two values didn't get promoted to long, the resulting value is also of type int and as such the resulting value is within the range of destination type

b) But if instead compiler did promote 100 and int.MaxValue; to type long before performing the addition, then i expression would cause an error due to violation of rule R1?!

thanx

Upvotes: 2

Views: 199

Answers (3)

Yet Another Geek
Yet Another Geek

Reputation: 4289

With the byte you are adding to integers, and then converting to a byte, thus causing an overflow when converting(implicitly). With integers overflows just resets to start from int.MinValue, so the result would be int i = int.MinValue + 199;

EDIT: The following is though possible

 byte b1 = (byte)255;
 byte b2 = (byte)255;
 byte b = (byte)(b1 + b2);

That is because both numbers are stored as bytes, and the sum is converted in runtime which would not make a constant expression (as b1 and b2 is not known as constants by the compiler).

Upvotes: 1

FlyingDeveloper
FlyingDeveloper

Reputation: 342

I think the key is that the following code is still "within the range of the destination type"

i = 100 + int.MaxValue + 100

After the overflow, i will evaluate to -2147483449 which is a valid integer.

When adding 255 to 255, the result is 510 (an integer) which is well outside the valid range for the byte type. No overflow happens here.

Hope that helps

Upvotes: 0

ChrisWue
ChrisWue

Reputation: 19070

Yes. The constants are all int by default, so the second statement will overflow happily and stay within int. You can see that it fails if you make one of the constants long:

byte b;
int i;

unchecked
{
    b = 255 + 255; //overflows
    i = 100L + int.MaxValue+100; // fails as well
}

Upvotes: 1

Related Questions