【发布时间】:2016-04-07 08:44:14
【问题描述】:
在 C 和 C++ 中,有符号整数上溢或下溢的行为是未定义的。
在 Java 和 C#(未经检查的上下文)中,行为似乎在一定程度上被定义。
根据 Java 规范,我们有:
整数运算符不以任何方式指示上溢或下溢。
还有:
Java 编程语言使用二进制补码表示整数 [...]
根据 C# 规范,我们有:
[...] 在未经检查的上下文中,溢出被忽略,任何不适合目标类型的高位被丢弃。
通过测试两者,我得到了预期的环绕结果。从规范的措辞来看,我觉得在 Java 中结果是可移植的(因为该语言需要 2 的补码表示),而 C# 可能有也可能没有这个结果(因为它似乎没有指定表示 -只是高阶位被丢弃)。
那么,两种语言规范是否保证在所有平台上的行为相同(只是措辞不同)?还是在我的测试用例(在 x86 和 Sun 的 JRE 和 Microsoft 的 .NET 下)它们只是碰巧彼此相同,但理论上在其他架构或实现上可能不同?
【问题讨论】:
-
如果行为是为语言明确定义的,为什么平台之间应该不同?!
-
@HannoBinder 当我使用术语 well-defined 时,我的意思是它与 undefined 形成对比——在 Java 和 C# 中都不是未定义的.但我仍然不明白规范是否说明了可移植结果或只是将行为保留为实现定义。
-
如果您查看System.Int32 documentation 中的Working with Non-Decimal 32-Bit Integer Values,您可以看到,至少对于整数而言,表示形式是相同的所有平台。我怀疑其他类型也一样。
-
即使使用 2 的补码,您也可以强制饱和(而不是环绕),并返回最高整数,正好在 2 的补码中。所以我不明白为什么这会推断出可移植性。
标签: java c# language-lawyer integer-overflow code-conversion