C#和Java规范在有符号整数溢出时是否阐明了相同的行为

本文关键字:是否 溢出 Java 整数 符号 | 更新日期: 2023-09-27 18:28:52

在C和C++中,有符号整数上溢或下溢的行为是未定义的。

在Java和C#(未检查的上下文)中,行为似乎在一定程度上得到了定义。


从Java规范来看,我们有:

整数运算符不会以任何方式指示溢出或下溢。

和:

Java编程语言使用整数的二补表示[…]


根据C#规范,我们有:

[…]在未检查的上下文中,会忽略溢出,并丢弃任何不适合目标类型的高阶位。


通过测试两者,我得到了预期的全面结果。从规范的措辞来看,我觉得在Java中,结果是可移植的(因为该语言需要2的补码表示),而C#可能有也可能没有这个结果(因为它似乎没有指定表示,只是丢弃了高阶位)。

那么,两种语言规范是否保证在所有平台上都有相同的行为(只是措辞不同)?或者,在我的测试用例中(在x86上,在Sun的JRE和Microsoft的.NET下),它们只是碰巧相同,但在其他体系结构或实现上理论上可能不同?

C#和Java规范在有符号整数溢出时是否阐明了相同的行为

在Java中,Java语言规范确保了可移植性,该规范规定了基元类型int的所有规则都是32位2的补码整数。然后,标准库本身实现了Integer类,该类封装了int值,并添加了一些方便的方法,但就范围和溢出而言,本质上是相同的。

在.NET中,CLR也定义了一些基元类型,这些基元类型也由不同的类和别名封装,具体取决于语言。参见通用语言规范,特别是通用类型系统。

因此,为了回答您的问题,在Java中,代码是可移植的,这是由Language Spec和JVM实现确保的。在.NET中(因为CLR也运行C++代码,而C++代码在更接近iron级别的操作中可能不符合CLS),您必须通过使代码符合CLS来确保代码是可移植的。好消息是,使用int和/或System.Int32可以使您符合CLS,便于移植。