The negative implication of this is noted in the man page:
NOTES Trying to take the absolute value of the most negative integer is not defined.
What's the reasoning behind this and what's the best recourse for a person who would like to avoid undefined behavior? Do I have to resort to something like:
unsigned uabs(signed val) {
return val > 0
? val
: (val == 1U << ((sizeof(val) * 8) - 1))
? -1U
: -val;
}
(Intentionally hacky to emphasize displeasure with stdlib ;-)
Example
Say you had a 4-bit signed value (for ease of understanding). unsigned max is 15, signed (positive) max is 7, signed (negative) min is -8, so abs(-8) won't fit into a signed value. Sure, you can represent it as -8, but then division and multiplication with the result don't work as expected.
The real answer to this question lies in the type promotion rules.
If I apply an arithmetic operator to an
unsigned int
and anint
, then theint
argument is promoted tounsigned
, and the result is alsounsigned
.If the
abs()
function returnedunsigned
, then it would cause this kind of type promotion of other values when it was used in an expression, which would cause unexpected results. For example, this code:Would print ">= 0", which many wouldn't like. The tradeoff, of not being able to use the single value
INT_MIN
, presumably seemed OK.