我不明白为什么下面的代码可以编译。
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
whatever s
的值可能是已知的。没有 Int16 operator+ (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);
关于c# - 为什么 C# 编译器不会因为这个明显的 'bad' 转换而提示溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9558154/