13

In C and C++, the behavior of signed integer overflow or underflow is undefined.

In Java and C# (unchecked contexts), the behavior seems to be defined to an extent.


From the Java specification, we have:

The integer operators do not indicate overflow or underflow in any way.

And:

The Java programming language uses two's-complement representation for integers [...]


From the C# specification, we have:

[...] In an unchecked context, overflows are ignored and any high-order bits that do not fit in the destination type are discarded.


By testing out both, I got the expected wrap-around result. Judging from the wording of the specs, I get the feeling that in Java the result is portable (because the language requires a 2's complement representation) while C# may or may not have that result (as it doesn't seem to specify a representation - only that the higher order bits are discarded).

So, do both language specifications guarantee the same behavior on all platforms (just with different wording)? Or do they simply happen to be the same with each other in my test case (on a x86 and under Sun's JRE and Microsoft's .NET), but could theoretically differ on other architectures or implementations?

StayOnTarget
  • 7,829
  • 8
  • 42
  • 59
Theodoros Chatzigiannakis
  • 26,988
  • 8
  • 61
  • 97
  • If the behavior is well defined for the language, why should it differ between platforms?! – JimmyB Jan 03 '16 at 17:23
  • 1
    @HannoBinder When I use the term *well-defined*, I mean it in contrast to *undefined* - neither in Java nor in C# is it undefined. But I still don't understand whether the spec spells out portable results or just leaves the behavior as *implementation-defined*. – Theodoros Chatzigiannakis Jan 03 '16 at 17:39
  • If you look at *Working with Non-Decimal 32-Bit Integer Values* in the [System.Int32 documentation](https://msdn.microsoft.com/en-us/library/system.int32.aspx) you can see that, at least for ints, the representation is the same across all platforms. I suspect it is the same for other types. – Fernando Matsumoto Jan 03 '16 at 19:27
  • 2
    Even with 2's compliment, you can enforce saturation (instead of wrap around), and return the highest integer, just in 2's compliment. So I don't get why that infers portability. – Reinstate Monica Jan 06 '16 at 23:48

1 Answers1

2

In Java the portability is ensured by Java Language Specification which states all the rules around primitive type intbeing signed 32bit 2's complement integer. Then the standard library itself implements Integer class which wraps int value and adds few convenience methods, but is essentially the same as far as the range and overflow are concerned.

In .NET there are primitive types defined by the CLR too and these too are wrapped by different classes and aliases depending on the language. See Common Language Specification - esp. Common Type Systtem.

So to answer your question, in Java the code is portable as ensured by Language Spec and JVM implementation. In .NET (since CLR runs also C++ code which in turn can be not CLS compliant operating at closer to the iron level) you have to make sure that your code is portable by making it CLS Compliant. Good news is that using int and/or System.Int32 makes you CLS compliant, ergo portable.

diginoise
  • 6,666
  • 1
  • 25
  • 32