与其说是错误,为什么不;t编译器将这两个字面值提升为type long
本文关键字:字面值 两个 long type 为什么不 错误 编译器 与其说 | 更新日期: 2023-09-27 17:50:08
以下两条语句将导致编译器溢出错误(原因是默认情况下会检查常量表达式是否溢出(:
int i=(int)(int.MaxValue+100); // error
long l=(long)(int.MaxValue+100); // error
但若编译器能够发现添加这两个值会导致溢出,为什么不将int.MaxValue
和100
都提升为long
,然后再尝试将它们添加在一起呢?据我所知,这应该不是问题,因为根据下面的引用,整数文字也可以是long
:类型
当整数文字没有后缀时,它的类型是这些类型中的第一个其中其值可以表示为:int,uint,long,ulong。
乙醇
文字100
可以表示为int
,这是这四种类型中按顺序排列的第一种,因此它被称为int
。
int.MaxValue
是而不是文字。它是一个类型为int
的公共常量字段。
因此,加法运算是int + int
,这导致int
,然后在这种情况下溢出。
要将文字100
转换为long
以便执行长整数加法,请在其后面加上L
:
long l = int.MaxValue + 100L;
规则是:
- int+int是int,不长
- 常量算术的默认值为"checked";非常量算术的默认值为"未检查">
- 100和int.MaxValue是常量
因此,根据规范,正确的行为是在编译时进行溢出检查并给出错误。
如果你说:
int x = 100;
int y = int.MaxValue;
long z = x + y;
然后正确的行为是对两个整数进行未经检查的相加,在溢出时进行环绕,然后将得到的整数转换为long。
如果你想要的是长算术,那么你必须这么说。将其中一个操作数转换为长。
原因都在序列中。如果你阅读你的代码,它会这样做:取一个值为MAX的int变量,然后加100。这在两种情况下都是真的,这是在发生其他事情之前执行的代码。
如果你想让它发挥作用。进行
long l = ((long)int.MaxValue)+100;
我想,简短的答案是因为它没有被设计成这样。每当MS向C#编译器添加功能时(或者当任何人向所有东西添加功能时(,都必须进行成本效益分析。人们必须想要这个功能,而实现这个功能的成本(就时间编码和测试以及可以实现的一些其他功能的机会成本而言(必须被这个功能为开发人员提供的潜在好处所抵消。
在您的情况下,让编译器执行您想要的操作的方法是简单、明显和清晰的。如果他们添加:
将仅由常量和文字组成的数字表达式的类型推断为可以包含结果值的最小类型
这意味着他们现在有更多的代码路径需要检查,也有更多的单元测试需要编写。改变预期行为也意味着,可能有人依赖于这个记录在案的事实,他的代码现在将无效,因为推断可能不同。
编译器不应该基于运行时表达式的结果来提升类型。
int.MaxValue
和100
都是整数。如果编译器根据表达式的结果更改类型,我会发现潜在的问题。
好吧,你期待什么?你说的是int.MaxValue+100
,它超过了integer
允许的最大值!要使其适用于long
,请执行以下操作:
((long)(int.MaxValue)) + 100;
不要以为编译器会自动将该值提升为long
。那就更奇怪了。