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

问题描述 投票:13回答:1

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

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


从Java规范,我们有:

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

和:

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


从C#规范,我们有:

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


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

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

java c# language-lawyer integer-overflow code-conversion
1个回答
2
投票

在Java中,Java Language Specification确保了可移植性,它规定了原始类型intbeing签名的32位2的补码整数的所有规则。然后标准库本身实现了包含Integer值的int类,并添加了一些便利方法,但就范围和溢出而言基本相同。

在.NET中,CLR也定义了原始类型,这些类型也由不同的类和别名包装,具体取决于语言。见Common Language Specification - esp. Common Type Systtem

因此,为了回答您的问题,在Java中,代码是可移植的,如语言规范和JVM实现所确保的那样。在.NET中(因为CLR也运行C ++代码,而C ++代码又不能在接近铁水平的情况下运行CLS),你必须确保你的代码是可移植的CLS Compliant。好消息是使用int和/或System.Int32使您符合CLS,ergo便携式。

© www.soinside.com 2019 - 2024. All rights reserved.