4

I'm confused as to why the result is converted into INT_MIN instead of integer overflow? Any ideas?

#include <stdio.h>

int ft_atoi(const char *str)
{
    int sign;
    int result;

    sign = 1;
    result = 0;
    while (*str == 32 || (*str >= 9 && *str <= 13))
        str++;
    if (*str == '+')
        str++;
    else if (*str == '-')
    {
        sign = -1;
        str++;
    }
    while (*str >= '0' && *str <= '9')
    {
        printf("before: %d\n", result);
        result = (result * 10) + *str - '0';
        printf("after: %d\n", result);
        str++;
    }
    return (sign * result);
}

int main(void)
{
    printf("%d\n", ft_atoi("-2147483648"));
    return (0);
}

Result:
e1z2r7p5% ./a.out
before: 0
after: 2
before: 2
after: 21
before: 21
after: 214
before: 214
after: 2147
before: 2147
after: 21474
before: 21474
after: 214748
before: 214748
after: 2147483
before: 2147483
after: 21474836
before: 21474836
after: 214748364
before: 214748364
after: -2147483648
-2147483648

bbeckca
  • 41
  • 3
  • 8
    What do you expect "*integer overflow*" to be? – alk Dec 17 '19 at 15:12
  • 8
    Signed integer overflow is undefined behavior. – Eugene Sh. Dec 17 '19 at 15:12
  • 2
    You're trying to make sense of undefined behavior. "Undefined" meaning, anything could happen. – Federico klez Culloca Dec 17 '19 at 15:13
  • To expand on what @EugeneSh. said, this means it can overflow to `INT_MIN` or some other value. It's up to the compiler/hardware. – Fiddling Bits Dec 17 '19 at 15:14
  • 6
    `2147483640 + 8 = -2147483648` on your platform, this is the expected "integer overflow" behaviour with 32 bit signed number types on most platforms. Same for `-2147483648 * -1 = -2147483648`. Multiplication with `-1` is an idempotent operation here, fascinating, isn't it? ;) – Ctx Dec 17 '19 at 15:15
  • Related: [Why is unsigned integer overflow defined behavior but signed integer overflow isn't?](https://stackoverflow.com/questions/18195715/why-is-unsigned-integer-overflow-defined-behavior-but-signed-integer-overflow-is). – Lundin Dec 17 '19 at 15:17
  • As for duplicates... there's the semi-nasty [How to explain undefined behavior to know-it-all newbies?](https://stackoverflow.com/questions/2235457/how-to-explain-undefined-behavior-to-know-it-all-newbies). – Lundin Dec 17 '19 at 15:18
  • 3
    Which instance of overflow are you referring to ? The last `result = (result * 10) + *str - '0';` or the `sign * result` ? – Sander De Dycker Dec 17 '19 at 15:19
  • 1
    The integer overflow happens to produce `INT_MIN` in this special case, but you should try some different inputs that result in integer overflow to convince yourself that it won't produce `INT_MIN` for all such inputs. (Well it _could_ do so because it is _undefined behavior_, but it won't on most implementations.) – Ian Abbott Dec 17 '19 at 15:27
  • @FedericoklezCulloca: “Undefined”, in the context of the C standard, does not mean anything can happen. It means the C standard does not impose any requirements. The C standard cannot say anything can happen because it has no power to nullify any other specifications. In other words, it can only **add** requirements; it cannot **take away** requirements. – Eric Postpischil Dec 17 '19 at 19:40
  • @EricPostpischil I should have specified that it's a form of speech, even though it is usually well understood when we talk about undefined behavior. You're the first one pointing that out to me. I'll keep that in mind next time I'll talk about UB. – Federico klez Culloca Dec 17 '19 at 20:00

1 Answers1

0

It can help to remember that a signed integer quantity uses the most-significant (leftmost ...) bit as a sign-bit: 0 is positive, 1 is negative. If you "add one" to a 32-bit integer 0x7FFFFFFF (all bits on except the leftmost), you'll probably get 0x80000000 (leftmost bit on, all others zero) which, because the leftmost bit is now on, is seen as "negative." And you might not get an "integer overflow" exception.

Mike Robinson
  • 8,490
  • 5
  • 28
  • 41
  • Although this is probably by far the most common implementation of signed integers, it's still implementation-dependent. The C standard leaves how a signed integer is represented up to the implementation. – PC Luddite Dec 18 '19 at 15:32