Re: Newbie - itoa implementation redux
- From: Eric Sosman <esosman@xxxxxxxxxxxxxxxxxxx>
- Date: Wed, 16 Aug 2006 08:36:56 -0400
Andrew Poelstra wrote:
On 2006-08-15, Eric Sosman <Eric.Sosman@xxxxxxx> wrote:
Andrew Poelstra wrote On 08/15/06 17:00,:It will result in a being 0, correct? Is there any case where that would[...]
This whole section could be replaced with:
int neg = (a < 0);
and placed above the previous line, which would become:
unsigned abs_a = neg ? -a : a;
This is much more compact, and IMHO, clearer.
... and perpetuates the same bug. As in the original,
evaluating `-a' when `a < -INT_MAX' can have undesirable
not be true?
It is possible that the result might be zero -- or forty-two,
or eleventy-one, or massive memory meltdown. Section 6.5, para 5:
"If an /exceptional condition/ occurs during the
evaluation of an expression (that is, if the result
is not mathematically defined or not in the range of
representable values for its type), the behavior is
So: If `a' is less than `-INT_MAX', then `-a' is greater than
`INT_MAX', which means it's outside the range of representable
values of `int'. The fact that the result (whatever it might
be) is later converted to `unsigned int' is of no consequence;
the damage has already occurred.
This can't happen on signed-magnitude or ones'-complement
systems, but it does happen on two's-complement machines where
`INT_MIN' equals `-INT_MAX-1'. Most implementations simply
ignore the overflow and produce the low-order bits of the too-
wide result, after which conversion to `unsigned int' will give
the "right" answer (which is certainly not zero). This outcome
is not guaranteed, though, and I have used machines that trapped
on integer overflow (granted, I wasn't using C).
And more importantly, how would one fix this bug? Since there's no type
guaranteed to be wider than an unsigned int, you'd have to handle negative
numbers as they are... which makes me wonder why it is necessary to take
the absolute value at all!
It's not necessary. In "The Standard C Library" P.J. Plauger
shows how to do the conversion by using non-positive numbers. His
code is a bit cumbersome because of C89's wishy-washiness about
how negative values work with the division and modulus operators;
C99 has tightened this up and his code could now be simplified.
The O.P.'s code had a comment showing a method that will work
on every machine I've run across:
> abs_a = -a ; //(1U - (1U + a));
.... and I think that changing it to `1U - (1 + a)' would make it
completely bullet-proof. (The issue: UINT_MAX is required to be
at least as large as INT_MAX, but I don't think it's required to
be larger -- although it has been on every machine I've used.)
str[--i] = 0;
This is only necessary in *your* version of the code;
it was not needed in the original.
Really? Where in the original is str null-terminated?
The original str has static duration and no explicit
initializer, hence it's initialized to all-elements-zero
before the program starts operating.
My personal preference would be to do it your way, just
in case a caller overwrites the '\0' at the end of the returned
string, leaving a time bomb for subsequent callers. Better to
refresh the '\0' each time than to hope it never gets clobbered --
still, as the code stood the '\0' was already present.
- Prev by Date: Re: || and &&
- Next by Date: 2004-2006 EXECryptor 2 years uncracked
- Previous by thread: Re: Newbie - itoa implementation redux
- Next by thread: Re: Newbie - itoa implementation redux