6

Please take a look at this simple program:

#include <iostream>
#include <vector>

using namespace std;

int main() {

vector<int> a;

std::cout << "vector size " << a.size() << std::endl;

int b = -1;

if (b < a.size())
   std::cout << "Less";
else
   std::cout << "Greater";

    return 0;
}

I'm confused by the fact that it outputs "Greater" despite it's obvious that -1 is less than 0. I understand that size method returns unsigned value but comparison is still applied to -1 and 0. So what's going on? can anyone explain this?

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
Andrey Chernukha
  • 21,488
  • 17
  • 97
  • 161
  • 2
    -1 unsigned is larger than 0 unsigned due to the high bit being set because it's negative. – Jesus Ramos Apr 27 '13 at 08:42
  • 1
    @JesusRamos - or, more abstractly, because the language definition says that values that don't fit in the range of an unsigned type are reduced modulo 2^n, where n is the number of bits used to represent the unsigned type. For twos-complement representations, the most common representation for integral types these days, this is, in fact, because the high bit is set. But other representations are also allowed. – Pete Becker Apr 27 '13 at 11:02
  • It's not even about being "abstract"; those are the rules of the language. C++ does not deal in "high bits"; it deals in contract. – Asteroids With Wings Mar 09 '20 at 22:42

3 Answers3

10

Because the size of a vector is an unsigned integral type. You are comparing an unsigned type with a signed one, and the two's complement negative signed integer is being promoted to unsigned. That corresponds to a large unsigned value.

This code sample shows the same behaviour that you are seeing:

#include <iostream>
int main()
{
  std::cout << std::boolalpha;
  unsigned int a = 0;
  int b = -1;
  std::cout << (b < a) << "\n"; 
}

output:

false

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
4

The signature for vector::size() is:

size_type size() const noexcept;

size_type is an unsigned integral type. When comparing an unsigned and a signed integer, the signed one is promoted to unsigned. Here, -1 is negative so it rolls over, effectively yielding the maximal representable value of the size_type type. Hence it will compare as greater than zero.

2

-1 unsigned is a higher value than zero because the high bit is set to indicate that it's negative but unsigned comparison uses this bit to expand the range of representable numbers so it's no longer used as a sign bit. The comparison is done as (unsigned int)-1 < 0 which is false.

Jesus Ramos
  • 22,940
  • 10
  • 58
  • 88
  • It's not about "high bits". It's about the rules. And the rules are that -1 converted to an unsigned int wraps around to the top of the unsigned int range. The bitwise representation couldn't be less relevant, even though it conveniently happens to match on many systems. – Asteroids With Wings Mar 09 '20 at 22:43