1

I have a problem when I use for loop in c++. It did not work as I thought. I am stuck begin from below short code:

#include <iostream>
#include<vector>
using namespace std;
int main() {
   vector<int> v;  //v.size() is 0 now
   for(int i=1;i<(v.size()-1);i+=2)
   {
      cout<<"i think this line will not be show!";
   }
   return 0;
}

This code print on console:

i think this line will not be show!

In above code. At for loop statement, variable i is initialized by 1, v.size()-1 will be -1 because v.size() is zero now. So, I think i<(v.size()-1) will be false and the for loop will be ignored and the program go to return statement without printing any character on console. But when I ran it I saw the for loop still work and print line i think this line will not be show!. I really dont understand how does the for loop work in this case. Can someone explain it for me! Thank you so much.

TaQuangTu
  • 2,155
  • 2
  • 16
  • 30
  • @JohnIlacqua You should post that as an answer instead of a comment. – Miles Budnek Oct 07 '18 at 03:46
  • 2
    `std::cout << (v.size()-1)` would have been a worth thing to print when you suspected the loop wouldn't iterate, but did anyway. There are *hundreds* of unsigned overflow/underflow questions on stack overflow. The biggest problem is nearly all of them have titles as seemingly unrelated to the issue as yours, so you can't really be blamed for not finding one. – WhozCraig Oct 07 '18 at 03:49

4 Answers4

4

v.size() returns a size_t, which is an unsigned integral type, which means it wraps around when it goes out of range. So size_t(0) - 1 is actually a very large number, since it can't be negative.

John Ilacqua
  • 906
  • 5
  • 19
1

std::vector<>::size() returns an integer of type std::vector<>::size_type, which is typically the same as std::size_t. std::size_t is an unsigned integer type, which means it can only take on positive values. When you say

i<(v.size()-1)

You are comparing i to the result of subtracting one from unsigned 0, because size() returns 0 and has an unsigned type. When you attempt to make an unsigned number negative, you will end up underflowing to the highest possible value that that unsigned type can take on. In other words, you're now comparing i to some really, really large number, such that it will always be less than it. To fix your program, you can cast the return value of size() to a signed type, like this:

i < (static_cast<long>(v.size()) - 1)
ThatsJustCheesy
  • 1,370
  • 14
  • 24
  • Thank you. Thank for your answer and @John llacqua's answer, I have knew why I got the bug. –  Oct 07 '18 at 04:11
0

the output is :

v.size()=0 , v.size()-1= 18446744073709551615 Program ended with exit code: 0

solution : cast the v.size to int ... , this will make the result -1 for ( ..., int(v.size())-1, ...)

BelloSoft
  • 1
  • 1
0

As @john said, the v.size() is size_t type, which is an unsigned integer. If you use a static analysis or enable appropriate warnings of compiler, clearly the something like "arithmetic operation between signed and unsigned integer" will be output.

So to avoid, the for loop may change to:

   for(int i=1;i+1<v.size();i+=2)
   {
      cout<<"i think this line will not be show!";
   }
khôi nguyễn
  • 626
  • 6
  • 15