1

When using int instead of std::size_t in this code sample

std::vector<int> v {1,2,3,4};
for(int i = 0; i < v.size(); i++)
{
  std::cout << v[i] << " ";
}

compiler generates following warning:

warning: comparison between signed and unsigned integer expressions

However program runs as expected and outputs:

1 2 3 4

I also notice those warnings quite often in projects I'm working on, that have been running years on production, and those warning never resulted in any problems on the side of our client. Since evidently those programs have no problem with comparing signed and unsigned integers, I would like to ask:

  • is there any benefit, performance or safety-wise, to always using unsigned over signed integers where applicable?
  • in what cases, if any, comparing signed and unsigned integer can result in errors or unexpected behavior?
  • if there is no good reason to worry about those warnings, is there any historical reason, why this information could be useful to developers in the past?
Reverent Lapwing
  • 283
  • 2
  • 11
  • 3
    You could (and should) easily fix that warning by writing `for(size_t i = 0; i < v.size(); i++)` – πάντα ῥεῖ Mar 07 '17 at 11:12
  • 1
    The signed and unsigned types have a common range of values representable in both types. As long as all values stay in that range, it works. As soon as a single value is outside that range, it breaks. – Bo Persson Mar 07 '17 at 11:14

2 Answers2

3

Comparing unsigned with signed can have serious problems, e.g.

std::string( "Bah" ).size() < -5

… will always be true.

That's the reason why you get warnings, but the compiler isn't smart enough, in the the time frame it has allotted, to see that any particular such comparison would be safe.

Now to your bullet point questions.

is there any benefit, performance or safety-wise, to always using unsigned over signed integers where applicable?

Yes, for correctness, avoiding UB. But, “applicable” is where you do bit level things. For numbers always prefer signed integer, or floating point type.

in what cases, if any, comparing signed and unsigned integer can result in errors or unexpected behavior?

When unsigned wrap-around gets involved, typically by implicit promotion of an operand from signed to unsigned.

if there is no good reason to worry about those warnings, is there any historical reason, why this information could be useful to developers in the past?

Not applicable.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
0

It's safe until you start comparing negative numbers.

Unsigned integer can hold twice as much as normal int, but can't hold negative values.

Vygintas B
  • 1,624
  • 13
  • 31