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 intand anint, then theintargument 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.