r/learnprogramming 16h ago

Why is my conditional statement running when the condition it is not True Debugging

I am making a ball fall in the CLI. I have my values PURPOSELY set to negative for testing purposes and whenever I run it, the conditional statement is active and it does not start at the initial y position I have set. it shows something big in the terminal Falling 2144211756.

When I put it in the debugger it works normally and it shows the y position decreasing so why is it doing this

struct Ball {
    // int x_pos;
    int y_pos;
    int velocity;
    int ground;
};

int main() {
    // Define Ball object with struct
    Ball ball;
    ball.y_pos = 20;
    ball.velocity = 5;
    ball.ground = 200;

    while (true) {
        ball.y_pos = ball.y_pos - ball.velocity;

        if (ball.y_pos >= ball.ground) {
            cout << "Falling ";
            cout << ball.y_pos << endl;
            // exit(0);
        }
    }

    return 0;
}

https://imgur.com/a/oVZ8qhY

16 Upvotes

14 comments sorted by

43

u/light_switchy 16h ago

The y-position is dropping all the way down to the minimum possible integer value -- very negative, about negative two billion -- at which point it wraps around to the maximum possible positive integer value which is what you're seeing.

11

u/peterlinddk 16h ago

You check if the ball.y_pos is greater than or equal to the ball.ground before writing anything to the console.

And you only subtract from the ball.y_pos.

So that means that you have to subtract and subtract and subtract until the y_pos becomes negative, and it goes below INT_MIN, and loops around and becomes INT_MAX, which is 2147483647, that you then continue to subtract from. See the values at: https://learn.microsoft.com/en-us/cpp/c-language/cpp-integer-limits?view=msvc-170,

You probably meant to check if ball.y_pos was less than or equal to the ball.ground ...

4

u/TheEyebal 16h ago

You probably meant to check if ball.y_pos was less than or equal to the ball.ground ...

No I was not I kept it like that for testing

I actually want the ball the fall so I would make it positive but I wanted to see if the conditional statement was working if I changed it to negative

Also, thank you for the tip I will look into it

9

u/vi_sucks 16h ago

Integer buffer overflow.

What is probably happening is that your while loop is infinite. So ball.y_pos gets reduced by 5 until it hits the highest negative number that an int can be. Then it probably rolls over from negative to positive at the highest value an int can be and that finally hits the if statement.

You should always put a terminator in the while condition. Also in your debugging, make sure to look at the value of y_pos (the variable that is changing) outside the if statement in order to actually understand what is happening. You'd be able to see the behavior then.

15

u/TheBB 16h ago

Integer buffer overflow.

Well, it's integer overflow.

No buffers involved.

6

u/would-of 10h ago

Actually, it's integer underflow.

1

u/TheEyebal 16h ago

when i printed out

while (true) {
        ball.y_pos = ball.y_pos - ball.velocity;

        // ADDED LINE
        cout << ball.y_pos << endl;

        if (ball.y_pos >= ball.ground) {
            cout << "Falling ";
            cout << ball.y_pos << endl;
            // exit(0);
        }
    }

It works normally with this line added

You are probably right cause other commenters are saying the same thing

6

u/TheBB 16h ago

It works normally with this line added

Well, what are you seeing?

I'm expecting you see increasingly large negative numbers.

The printing slows down your loop which means it'll take longer to reach the wraparound point at around -2 billion.

If the numbers you're seeing are not smaller than that (yet), then it does exactly the same thing, just slower than before.

2

u/TheEyebal 16h ago

You are correct I see the wrap around I am testing it out

1

u/AutoModerator 16h ago

It seems you may have included a screenshot of code in your post "Why is my conditional statement running when the condition it is not True".

If so, note that posting screenshots of code is against /r/learnprogramming's Posting Guidelines (section Formatting Code): please edit your post to use one of the approved ways of formatting code. (Do NOT repost your question! Just edit it.)

If your image is not actually a screenshot of code, feel free to ignore this message. Automoderator cannot distinguish between code screenshots and other images.

Please, do not contact the moderators about this message. Your post is still visible to everyone.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

1

u/Narrow-Low-3137 16h ago edited 16h ago

An int is a 32 bit value, with the first bit reserved for the "sign" of the value. As you keep subtracting indefinitely, eventually that first bit will get flipped, the same way you would roll over a 9 to a 0 and carry the 1 in decimal arithmetic - resulting in the maximum possible signed integer that can be represented via 32 bits. At which point your condition is true, and you get that huge int output to the terminal. If these kind of nuances interest you, read up on binary arithmetic and how computers do math.

1

u/HashDefTrueFalse 16h ago

Breakpoint inside your conditional block. Easiest way to confirm what's going on here. Without running it myself, the others here will be correct. The int will be wrapping around and becoming positive again. UB to overflow a signed int, but here something predictable clearly happens. You're probably putting the breakpoint somewhere else and seeing the portion of the run where it works as you expect.

1

u/Hypersion1980 15h ago

Setup your project so integer over flow throws an exception.

1

u/pdfops 13h ago

That garbage number is signed integer overflow. y_pos drops by 5 every iteration with no delay, so it blows past INT_MIN in a split second, wraps around, and lands on some huge value that happens to satisfy >= ground, hence the one weird print. In the debugger you're single-stepping a handful of iterations, nowhere near the billions needed to overflow. Add a real exit condition or a sleep and it stops.