TTroy said:
Hello, can anyone explain why the following function will not work for
INT_MIN:
-- Snip itoa() from KnR2, pg 64. --
I've narrowed it down to the n = -n line. On my machine, -(INT_MIN)
would be 1 more than INT_MAX. Does this overflow the temporary value
-n, or the actual object n. What I'm trying to ask is, when the fault
happens?
My feeling is that the fault (undefined behaviour) first occurs with
the -n, because the value of the result is a signed int (no promotions
or conversions) and that value is overflowed. Does that make sense?
Can a "value" overflow just like objects can?
Does anyone know how to fix this function to allow it to accept any
integer argument (including INT_MIN on 2's complement machines)?
Isn't this straight out of KnR2, Exercise 3-4?
Basically, you're right, in two's complement, the absolute value of
INT_MIN is one greater than INT_MAX. Therefore, setting int i = INT_MIN
* -1; results in overflow (in two's complement).
In the itoa function above,
do /* generate digits in reverse order */
{
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
runs once, and then the while loop ends because n is still negative
because of the overflow.
The '-' is added:
if (sign < 0)
s[i++] = '-';
and then the string is terminated and reversed.
There are many ways to write this function, you just have to catch the
case of INT_MIN, either explicitly, e.g.:
if(n == INT_MIN) /* do something to prevent overflow */
or implicitly in a way that converts the INT_MIN into something safe to
assign into an integer.