c# - 为什么 C# 编译器不会因为这个明显的 'bad' 转换而提示溢出?

标签 c# .net compiler-construction clr 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;

sInt16 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/

相关文章:

c# - 如何在 SilverLight 项目中使用 XDocument 类 (C#)

c# - 计算年、月、周和日

c# - 哪个更利于可读性?

objective-c - 每个文件都是用 Objective-C 编译的吗?

c# - 编译器错误CS1061

c# - .NET SVCUTIL 未正确生成命名空间

c# - session 变量在不同浏览器之间共享吗?

c# - 如何读取许可证文件

.net - 用户控件数据绑定(bind)的最佳实践 - 如何实现?

swift - Swift 中的自定义运算符