Change the function
abs() to return unsigned integers, instead of signed integers as it does today.
The documentation for
Int::min_value() will be returned
if the number is
Int::min_value(). This subtlety can lead to bugs, because a developer may count
abs() to return a positive value. And forcing every caller of
abs() to know about this corner
case and handle it, is not a very nice design.
abs() is changed to return an unsigned integer of the same width as its input, there is no
special case to handle. Code calling
abs() is cleaner because it does not have to handle
Int::min_value(), and will lead to fewer bugs.
Because (for example)
-127i8 happens to have the same binary representation as
128u8, this is
basically a free operation.
Consider how code that calls the current version of
abs() can ensure its result is positive:
- Proof by reasoning about your code that the input of
abs()will never be
- Do a runtime check before calling
abs(), and somehow handle it or return an error.
- Cast the input to a wider signed integer (if available) before calling
- Cast the result of
abs()to an unsigned integer of the same size.
In all cases this requires extra work for the code calling abs. With this proposal option 4 will be the default, while option 1 to 3 remain possible. The default behaviour will lead to correct (positive) results for all inputs.
It is not possible anymore to do:
let mut a: i8 = -15; a = abs(a);
let mut a: i8 = -15; a = abs(a) as i8; // may overflow
This may actually be an advantage, as now the user code is the cause of the overflow, and not
Keep the status quo, which can lead to subtle bugs or code that is less clean.
Basically this is not a new idea, see https://github.com/rust-lang/rust/issues/2353 and http://www.reddit.com/r/rust/comments/2cykyz/abs_for_minimum_int_values/. Is this the proper way to suggest such a change? Would it still be possible before 1.0 (abs is not yet stable)? This is a trivial change, and I have a working sample implementation.