Integer summing blues, short += short problem

C#TypesIntShort

C# Problem Overview


Program in C#:

short a, b;
a = 10;
b = 10;
a = a + b; // Error : Cannot implicitly convert type 'int' to 'short'.

// we can also write this code by using Arithmetic Assignment Operator as given below

a += b; // But this is running successfully, why?

Console.Write(a);

C# Solutions


Solution 1 - C#

There are two questions here. The first is "why is short plus short result in int?"

Well, suppose short plus short was short and see what happens:

short[] prices = { 10000, 15000, 11000 };
short average = (prices[0] + prices[1] + prices[2]) / 3;

And the average is, of course, -9845 if this calculation is done in shorts. The sum is larger than the largest possible short, so it wraps around to negative, and then you divide the negative number.

In a world where integer arithmetic wraps around it is much more sensible to do all the calculations in int, a type which is likely to have enough range for typical calculations to not overflow.

The second question is:

  • short plus short is int
  • assigning int to short is illegal
  • a +=b is the same as a = a + b
  • therefore short += short should be illegal
  • so why is this legal?

The question has an incorrect premise; the third line above is wrong. The C# specification states in section 7.17.2

> Otherwise, if the selected operator is > a predefined operator, if the return > type of the selected operator is > explicitly convertible to the type of > x, and if y is implicitly convertible > to the type of x or the operator is a > shift operator, then the operation is > evaluated as x = (T)(x op y), where T > is the type of x, except that x is > evaluated only once.

The compiler inserts the cast on your behalf. The correct reasoning is:

  • short plus short is int
  • assigning int to short is illegal
  • s1 += s2 is the same as s1 = (short)(s1 + s2)
  • therefore this should be legal

If it did not insert the cast for you then it would be impossible to use compound assignment on many types.

Solution 2 - C#

Well, the += operator says you'll be increasing the value of a with a short, while = says you'll overwrite the value, with the result of an operation. The operation a + b yields an int, not knowing that it can do otherwise, and you're trying to assign that int to a short.

Solution 3 - C#

You have to use:

a = (short)(a + b);

As to the difference between the behaviours of assignment and addition assignment, I imagine it has something to do with this (from msdn)

x+=y
is equivalent to
x = x + y
except that x is only evaluated once. The meaning of the + operator is
dependent on the types of x and y (addition for numeric operands, 
concatenation for string operands, and so forth).

However, it's a bit vague, so mabye someone with a deeper understanding can comment.

Solution 4 - C#

This happens because int is the smallest signed type for which + is defined. Anything smaller is first promoted to int. The += operator is defined with respect to +, but with a special-case rule for handling results that don't fit the target.

Solution 5 - C#

This is because += is implemented as an overloaded function (one of which is a short, and the compiler chooses the most specific overload). For the expression (a + b), the compiler widens the result to an int by default before assigning.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMohammad Jahangeer AnsariView Question on Stackoverflow
Solution 1 - C#Eric LippertView Answer on Stackoverflow
Solution 2 - C#David HedlundView Answer on Stackoverflow
Solution 3 - C#UpTheCreekView Answer on Stackoverflow
Solution 4 - C#Marcelo CantosView Answer on Stackoverflow
Solution 5 - C#Stefan MaiView Answer on Stackoverflow