0

I have a particular use case where I have to initialize i value in for loop to -1 and write the exiting condition based on vector size. But the problem is the loop is not getting executed at all. This is the code.

#include <bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> vec = { 1, 2, 3, 4, 5 };
    for(int i=-1;i<vec.size();i++) cout << i << " ";
    return 0;
}

But I am able to do like this.

#include <bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> vec = { 1, 2, 3, 4, 5 };
    int size = vec.size();
    for(int i=-1;i<size;i++) cout << i << " ";
    return 0;
}

Can anyone explain this weird behavior or am I doing something wrong there?

  • You are comparing an `int` and a `vector::size_type` (aka `size_t`), which is unsigned. Change the type of `i` to `size_t`. – Marshall Clow Jul 21 '22 at 02:47
  • See https://stackoverflow.com/questions/5416414/signed-unsigned-comparisons – Marshall Clow Jul 21 '22 at 02:48
  • @MarshalClow OP says *I have to initialize i value in for loop to -1* ... that would be tricky if `i` is a `size_t`. – Adrian Mole Jul 21 '22 at 02:50
  • There are numerous posts on Stack Overflow explaining that the return type of a vector's `size()` function is an **unsigned** integer value and how to deal with that. I can't find a *specific* example of wanting to start a loop from -1, but search this site for "[c++] vector size unsigned" and you'll likely get some ideas. – Adrian Mole Jul 21 '22 at 02:53
  • ... but, you can either use your second code snippet or cast the `vec.size()` result to an `int` ... assuming the size of the vector will never be larger than `INT_MAX`. – Adrian Mole Jul 21 '22 at 02:55

1 Answers1

1

i<size() in the first snippet compares a signed int i; to an unsigned size_t size; (size_t is the typical typedef for vector::size_type)

When the compiler sees that comparison, it converts the int to an unsigned value. Typically something like 2^64 - 1, for your first value of -1. This value is much bigger than 5, so the loop doesn't run.

Take-away: Don't compare signed and unsigned value with less-than or greater-than.

In fact, in a modern world you can compare signed and unsigned using std::cmp_less https://en.cppreference.com/w/cpp/utility/intcmp

Jeffrey
  • 11,063
  • 1
  • 21
  • 42
  • Why does the compiler convert the int to an unsigned? Why can't it convert the unsigned to an int? – Adrian Mole Jul 21 '22 at 03:01
  • This is what the standard specifies. See https://stackoverflow.com/questions/5416414/signed-unsigned-comparisons – Jeffrey Jul 21 '22 at 03:03
  • 1
    So what about a system (though it would be unusual) where `int` is 64 bits and `size_t` is 32 bits? OP's *first* code snippet would probably work, then. – Adrian Mole Jul 21 '22 at 03:08
  • ... BTW, I'm not deliberately trying to be awkward, Just trying to offer hints as to how your answer can be improved. Sorry if I have come across as being a bit truculent. – Adrian Mole Jul 21 '22 at 03:10