C# · 12月 24, 2021

为什么C#编译器不会抱怨Overflow这个明显的“糟糕”演员?

我不明白为什么下面的代码编译. public void Overflow(){ Int16 s = 32767; s = (Int16) (s + 1);}

在编译时,显然(s 1)不是Int16,因为我们知道s的价值.

而CLR允许投射到:

>到自己的类型
>或任何基础类型(因为它是安全的)

由于Int32不是Int16,Int16不是Int32的基本类型.

问题:为什么编译器不会失败上面的转换?你可以从CLR和编译器的角度来看看吗?

谢谢

解决方法 表达式s 1的类型是Int32 – 在执行加法之前,两个操作数都将转换为Int32.所以你的代码相当于: public void Overflow(){ Int16 s = 32767; s = (Int16) ((Int32) s + (Int32) 1);}

所以溢出只会在显式转换中发生.

或者换句话说:因为语言规范这样说.你应该描述一个:

>为什么你认为编译器违反了语言规范
>您提出的语言规范的确切变化

编辑:只是为了使事情真的很清楚(根据你的意见),编译器不会允许这样做:

s = s + 1;

当s是Int16时,无论s的值可能被认为是什么.没有Int16运算符(Int16,Int16)运算符 – 如C#4规范的7.8.4节所示,整数加法运算符是:

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