C#和Java规范在有符号整数溢出时是否阐明了相同的行为
本文关键字:是否 溢出 Java 整数 符号 | 更新日期: 2023-09-27 18:28:52
在C和C++中,有符号整数上溢或下溢的行为是未定义的。
在Java和C#(未检查的上下文)中,行为似乎在一定程度上得到了定义。
从Java规范来看,我们有:
整数运算符不会以任何方式指示溢出或下溢。
和:
Java编程语言使用整数的二补表示[…]
根据C#规范,我们有:
[…]在未检查的上下文中,会忽略溢出,并丢弃任何不适合目标类型的高阶位。
通过测试两者,我得到了预期的全面结果。从规范的措辞来看,我觉得在Java中,结果是可移植的(因为该语言需要2的补码表示),而C#可能有也可能没有这个结果(因为它似乎没有指定表示,只是丢弃了高阶位)。
那么,两种语言规范是否保证在所有平台上都有相同的行为(只是措辞不同)?或者,在我的测试用例中(在x86上,在Sun的JRE和Microsoft的.NET下),它们只是碰巧相同,但在其他体系结构或实现上理论上可能不同?
在Java中,Java语言规范确保了可移植性,该规范规定了基元类型int
的所有规则都是32位2的补码整数。然后,标准库本身实现了Integer
类,该类封装了int
值,并添加了一些方便的方法,但就范围和溢出而言,本质上是相同的。
在.NET中,CLR也定义了一些基元类型,这些基元类型也由不同的类和别名封装,具体取决于语言。参见通用语言规范,特别是通用类型系统。
因此,为了回答您的问题,在Java中,代码是可移植的,这是由Language Spec和JVM实现确保的。在.NET中(因为CLR也运行C++代码,而C++代码在更接近iron级别的操作中可能不符合CLS),您必须通过使代码符合CLS来确保代码是可移植的。好消息是,使用int
和/或System.Int32
可以使您符合CLS,便于移植。