3 ms·
In fact, prior to Java 8, you could not even declare unsigned integers. In Java 8 you still can't declare unsigned integers. It just that API have been extende
by wuch 11y ago
In fact, prior to Java 8, you could not even declare unsigned integers.
In Java 8 you still can't declare unsigned integers. It just that API have been
extended to provide operations that treat an int or a long as having unsigned
value.
This seems to imply that Java leaves the behaviour of signed integer overflow
up to the underlying hardware, but guarantees a two's complement
representation even if the architecture does not. It seems reasonable to
expect that it would simply wrap to 0 (I wasn't able to find a more
conclusive reference for this).
In fact Java Specification does specify what happens in case of overflow very
precisely. For example for multiplication (section 15.17.1):
If an integer multiplication overflows, then the result is the low-order bits
of the mathematical product as represented in some sufficiently large
two's-complement format.
And for addition (section 15.18.2):
If an integer addition overflows, then the result is the low-order bits of the
mathematical sum as represented in some sufficiently large two's-complement
format.
Java approach without undefined behaviour would seem to be quite convenient for
a programmer, but it does not seem to be the case in practice. Of course you
gain ability to check for overflow after performing the operation, which is
nice, but at the same time loose the straightforward way to detect bugs
provided by undefined behaviour (UB).
If an application executes UB, then it is obviously wrong, thus a simple
instrumentation of arithmetic operation followed by a check for overflow gives
a way to detect such problems without false positives (see for example
-fsanitize=undefined and similar options available in modern C/C++ compilers).
IMHO only very small fraction of overflow bugs would have been fixed by just
wrapping result around.
- cautious_int 11y agoOf course you gain ability to check for overflow after performing the operation, Using exceptions? IMHO only very small fraction of overflow bugs would have been fixed by just wrapping result around. Yes, switching to wrapping integers is not the solution to overflow. Rather check the operation beforehand. I still think using unsigned integers is always preferred if you don't need negative values.
- wuch 11y agoWhat I had in mind, is the fact that with defined overflow you could unconditionally perform the operation, and then observe the result to decide if overflow have in fact happened. For example, following pattern to check if adding 100 to an integer 'a' overflows would be valid: int a = ...; if (a + 100 < a) overflow So this is one of cases where wrapping behaviour could potentially fix bugs in existing applications. Obviously, rewriting this to work with overflow is trivial if you are already aware of undefined behaviour that could occur.
- cautious_int 11y agoHow would that fix existing code without modifying it?
- wuch 11y agoSuppose somebody have written above code. Then under current C++ standard it would invoke UB on overflow. But, if standard were to change and require wrapping behaviour for int, then it would be "fixed", i.e, do what programmer intended it to do. Similarly if you use some compiler specific option to ensure wrapping behaviour for signed integers like GCC -fwrapv.
- cautious_int 11y agoOh, you are assuming someone actually wrote that code. That is circular reasoning. It would be much better to write proper checks or just call functions that do so.