-6

Why does this result run into infinite loop?

After entering the for loop, I printed values of i and v.size()-2 and they are 0 and -1 respectively. Hence, the loop condition must be false. Then, how does this program get into the for loop in the first place?

#include <iostream>
#include <vector>

int main() {
    std::vector<int> v {1};
    std::cout << "Size:: " << v.size();
    for (int i=0 ; i <= (v.size()-2) ; i++) {
        std::cout << "Hello";
    }
    return 0;
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 2
    Where exactly are you "printing the value of v.size()-2"? – Kerrek SB Feb 04 '17 at 15:18
  • Your program presumably has undefined behaviour because `i++` causes signed integer overflow. – Kerrek SB Feb 04 '17 at 15:20
  • 7
    Your compiler should have warned you about that signed-unsigned comparison. If it didn't, find out how to increase its warnings. – molbdnilo Feb 04 '17 at 15:21
  • The right tool to solve such problems is your debugger. You should step through your code line-by-line *before* asking on Stack Overflow. For more help, please read [How to debug small programs (by Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). At a minimum, you should \[edit] your question to include a [Minimal, Complete, and Verifiable](http://stackoverflow.com/help/mcve) example that reproduces your problem, along with the observations you made in the debugger. – πάντα ῥεῖ Feb 04 '17 at 15:24
  • @KerrekSB: Isn't the `<=` comparison already undefined behaviour because `v.size()` is 1, so `i` is compared to a number bigger than the maximum `int`? – Christian Hackl Feb 04 '17 at 15:35
  • 1
    @ChristianHackl: You can't compare a number with one too big for its type, because the operands are converted to a common type first. – Kerrek SB Feb 04 '17 at 15:40
  • @KerrekSB: Actually, forget my comment. Of course `i` is converted to `size_t` first, so it's the `++` which eventually causes overflow and UB. – Christian Hackl Feb 04 '17 at 15:40
  • @πάνταῥεῖ , i did step through gdb and was expecting that i don't step into for loop, but when i got into for loop the value of (v.size()-2) was -1 , and hence the question how did i get into this loop at first place. – Prashant Nidgunde Feb 04 '17 at 16:42

1 Answers1

8

The problem is in comparing to an unsigned number after an underflow.

The size of the vector is 1. You subtracr 2, and get -1 mathematically. In unsigned math, however, you get a very large number, so your loop continues for much longer than you expected.

To avoid situations like this, replace subtraction with addition:

i+2 <= v.size()
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • More on what if a negative number is assigned to an unsigned integer is here : http://stackoverflow.com/questions/2711522/what-happens-if-i-assign-a-negative-value-to-an-unsigned-variable – Prashant Nidgunde Feb 04 '17 at 23:08