Checked arithmetic
In PolicyCenter version 8.0 and earlier versions, numeric values could exceed their defined bounds in arithmetic operations. For example, if you multiplied the maximum integer value by 2, the result by definition exceeds the range of integer values. Not only is the result value incorrect, the result could be positive when you expect it to be negative, or negative when you expect it to be positive. Because no Gosu exceptions occurred, it was difficult to protect against overflow errors, which could cause unexpected behavior or security issues.
In version 9.0, Gosu includes an optional
feature called checked arithmetic.
If checked arithmetic is enabled, Gosu behavior for the standard arithmetic
operators changes for addition, subtraction, and multiplication. In nearly
all cases, the result is the same and the behavior is the same. In the
rare case that arithmetic overflow occurs, Gosu throws the exception
ArithmeticException. To
enable checked arithmetic, set Java system property checkedArithmetic to true.
Gosu checked arithmetic includes protection
only for the operators +,
-, and *. There is no protection for
division, which only affects the expression Integer.MIN_VALUE / -1.
There are special cases in which arithmetic
overflow behaviors are desirable for operators +, -, and *. For example, some common hash
algorithms rely on arithmetic overflow. To handle typical use cases in
overridden hashCode methods,
Gosu always compiles hashCode
methods with checked arithmetic disabled.
For other cases in which arithmetic overflow
behaviors are desirable, you can use three new Gosu operators that ensure
unchecked arithmetic independent of the Java system property checkedArithmetic. The new operators
are the standard arithmetic operators prefaced with an exclamation point
character: !+, !-, and !*.
For example, with Java system property
checkedArithmetic to true:
var four = new Integer(4)
var y = Integer.MAX_VALUE * 2 + four // This line throws ArithmeticException
In contrast, the following example uses the unchecked
arithmetic operator !*,
which is only for special circumstances in which overflow is desirable:
var four = new Integer(4)
var x = Integer.MAX_VALUE !* 2 + four // This line does not throw ArithmeticException
print(x) // print "2"
Because the arithmetic in the second example is unchecked,
the result that prints 2
successfully is possibly unexpected and invalid.
