2

I do understand why this produce compile time-error:

short x = 1;
short y = 2;
short z = x + y; // compile-time error

I've grasped why this runs without any issues:

short x = 1;
short y = 2;
x += y; // all right, because of c# specs section 7.17.2

But I've got no clue why this also works:

short x = (short)1 + (short)2;

I expected to get the same compile-time error as in the first example, but it runs successfully... Why?

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
ChernikovP
  • 471
  • 1
  • 8
  • 18
  • 2
    Perhaps because in your last example, the compiler detects a constant value? – spender Sep 15 '14 at 21:02
  • This is actually not a duplicate of the linked post - the OP specifically called out the behavior in that post... (http://stackoverflow.com/questions/4343624/integer-summing-blues-short-short-problem) – Reed Copsey Sep 15 '14 at 21:05
  • + operator will return whatever type is on the (right/left??) I forget which one but since you have the same type on both sides of + it returns that type. – RadioSpace Sep 15 '14 at 21:10
  • @RadioSpace that's not necessarily true. In C#, short + short returns an int. – Reed Copsey Sep 15 '14 at 21:12
  • It is really the other way around. It wants a cast because the expression can overflow so easily in an undetectable way and wants you to acknowledge that you thought about that problem. They could not think of a decent syntax to enforce the cast for +=. These casts are not necessary in VB.NET but it checks for overflow by default. Which is "better" but it is very expensive. Not the C# way. – Hans Passant Sep 15 '14 at 21:20
  • @RadioSpace: There's no such rule. The smaller operand promotes to the size of the bigger one, or `int` if both are smaller. C++ has the same rule, btw, but also has an implicit conversion back to the smaller size so it is only a warning, not an error. – Ben Voigt Sep 15 '14 at 22:49

3 Answers3

3

Since you're using constant values, the compiler can detect that it's allowable, evaluate it at compile time, and let it execute. The generated IL evaluates to the same as typing short x = 3;.

Note the following also works (for the same reason):

const short x = 1;
const short y = 2;
short z = x + y; 

But this fails:

const short x = 32000;
const short y = 32001;
short z = x + y;

Note that this is covered in the C# Language Spec, 6.1.9 Implicit constant expression conversions:

  • 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.
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
2

Your last snippet just compiles to constant 3. Compiler doesn't need to call any operators in int it just computes and stores the value at compile time.

it is same as short x = 3;

Here is the generated IL

IL_0001:  ldc.i4.3    //Load the constant 3 into evaluation stack
IL_0002:  stloc.0     // stores the value in stack to x
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
1

I've got no clue why this also works:

short x = (short)1 + (short)2;

The compiler evaluates the rhs expression at compile time and can prove that the result is within bounds.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490