以下两个语句将导致编译器溢出错误(原因是默认情况下检查常量表达式是否溢出):
int i=(int)(int.MaxValue+100); // error
long l=(long)(int.MaxValue+100); // error
但是如果编译器能够确定添加这两个值会导致溢出,那么为什么它不会将int.MaxValue
和100
同时提升为long
,然后才尝试把它们加在一起?据我所知,这应该不是问题,因为根据以下引用,整数文字也可以是long
类型:
当整数文字没有后缀时, 它的类型是这些类型中的第一种 其值可以表示为: int,uint,long,ulong。
感谢名单
答案 0 :(得分:10)
文字100
可以表示为int
,这是该顺序中这四种类型中的第一种,因此它是int
。
int.MaxValue
不是文字。它是int
类型的公共常量字段。
因此,添加操作为int + int
,结果为int
,然后在这种情况下溢出。
要将文字100
转换为long
,以便执行长整数加法,后缀为L
:
long l = int.MaxValue + 100L;
答案 1 :(得分:7)
规则是:
因此,根据规范的正确行为是在编译时进行溢出检查并给出错误。
如果相反,你说:
int x = 100;
int y = int.MaxValue;
long z = x + y;
然后正确的行为是对两个整数进行未经检查的添加,在溢出时回绕,然后将得到的整数转换为long。
如果您想要的是长算术,那么您必须这样说。将其中一个操作数转换为long。
答案 2 :(得分:4)
原因在于序列中的所有内容。如果你读了你的代码,它会这样做:取一个值为MAX的int变量,然后加100。在这两种情况下都是如此,这是在其他任何事情发生之前执行的代码。
如果你想让它发挥作用。做
long l = ((long)int.MaxValue)+100;
答案 3 :(得分:3)
根据运行时表达式的结果,不是编译器提升类型的地方。
int.MaxValue
和100
都是整数。如果编译器根据表达式的结果更改类型,我会发现可能出现问题。
答案 4 :(得分:3)
我想,简短的答案是因为它没有被设计成。每当MS向C#编译器添加功能时(或当任何人向任何添加功能时),都必须进行成本效益分析。人们不得不想要这个功能,实现功能的成本(在时间编码和测试方面以及可以实现的某些其他功能的机会成本)必须被潜在的好处所抵消。该功能提供给开发人员。
在您的情况下,让编译器执行您想要的操作的方法很简单,明显且清晰。如果他们补充:
将仅包含常量和文字的数值表达式的类型推断为可包含结果值的最小类型
这意味着他们现在有更多的代码路径可供检查,还有更多的单元测试可供编写。改变预期的行为也意味着可能有人依赖于这个记录的事实,其代码现在将无效,因为推论可能不同。
答案 5 :(得分:1)
那么,你期待什么?您说int.MaxValue+100
超过integer
允许的最大值!要使其适用于long
,请执行以下操作:
((long)(int.MaxValue)) + 100;
不要假设编译器会自动将值提升为long
。那会更奇怪。