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

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

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


从Java规范中,我们有:

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

和:

Java编程语言使用二进制补码表示整数[...]


从 C# 规范中,我们有:

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


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

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


答案 1

在Java中,可移植性由Java语言规范保证,该规范规定了所有关于基元类型的规则,这些规则都是有符号的32bit 2的补码整数。然后,标准库本身实现了类,该类包装值并添加了一些方便的方法,但就范围和溢出而言,它本质上是相同的。intIntegerint

在 .NET 中,CLR 也定义了基元类型,这些基元类型也由不同的类和别名包装,具体取决于语言。请参阅公共语言规范 - 特别是公共类型系统

因此,为了回答您的问题,在Java中,代码是可移植的,正如语言规范和JVM实现所保证的那样。在.NET中(因为CLR也运行C++代码,而这些代码又可能不符合CLS,在更接近铁的水平上运行),你必须通过使其符合CLS来确保代码是可移植的。好消息是,使用和/或使您符合CLS标准,因此可移植。intSystem.Int32


答案 2

推荐