Search code examples
c#.netoverflowclr

Why does C# compiler does not complain with Overflow for this obvious 'bad' casting?


I cannot understand why the code below compiles.

public void Overflow()
{
    Int16 s = 32767;
    s = (Int16)  (s + 1);
}

At the compile time it is obvious that (s+1) is not a Int16 anymore as we know the value of s.

And CLR allows casting to :

  • To its own type
  • Or any of the base-types (because it is safe)

As Int32 is not Int16 and Int16 is not base type of Int32.

Question: So why the compiler does not fail for the casting above? Can you please explaint it from the CLR and compiler point of view?


Solution

  • The type of the expression s + 1 is Int32 - both operands are converted to Int32 before the addition is performed. So your code is equivalent to:

    public void Overflow()
    {
        Int16 s = 32767;
        s = (Int16)  ((Int32) s + (Int32) 1);
    }
    

    So the overflow only actually occurs in the explicit cast.

    Or, to put it another way: because the language specification says so. You should describe one of:

    • Why you think the compiler is violating the language specification
    • The exact change you're proposing to the language specification

    EDIT: Just to make things really clear (based on your comments), the compiler wouldn't allow this:

    s = s + 1;
    

    when s is an Int16 whatever the value of s might be known to be. There's no Int16 operator+ (Int16, Int16) operator - as shown in section 7.8.4 of the C# 4 spec, the integer addition operators are:

    int operator +(int x, int y);
    uint operator +(uint x, uint y);
    long operator +(long x, long y);
    ulong operator +(ulong x, ulong y);