What is wrong with my For loops? i get warnings: comparison between signed and unsigned integer expressions [-Wsign-compare]

Why is there a warning with -Wsign-compare ?

As the name of the warning, and its text, imply, the issue is that you are comparing a signed and an unsigned integer. It is generally assumed that this is an accident.

In order to avoid this warning, you simply need to ensure that both operands of < (or any other comparison operator) are either both signed or both unsigned.

How could I do better ?

The idiomatic way of writing a for loop is to initialize both the counter and the limit in the first statement:

for (std::size_t i = 0, max = vec.size(); i != max; ++i)

This saves recomputing size() at each iteration.

You could also (and probably should) use iterators instead of indices:

for (auto it = vec.begin(), end = vec.end(); it != end; ++it)

auto here is a shorthand for std::vector<int>::iterator. Iterators work for any kind of containers, whereas indices limit you to C-arrays, deque and vector.


It is because the .size() function from the vector class is not of type int but of type vector::size_type

Use that or auto i = 0u and the messages should disappear.


You get this warning because the size of a container in C++ is an unsigned type and mixing signed/unsigned types is dangerous.

What I do normally is

for (int i=0,n=v.size(); i<n; i++)
    ....

this is in my opinion the best way to use indexes because using an unsigned type for an index (or the size of a container) is a logical mistake.

Unsigned types should be used only when you care about the bit representation and when you are going to use the modulo-(2**n) behavior on overflow. Using unsigned types just because a value is never negative is a nonsense.

A typical bug of using unsigned types for sizes or indexes is for example

// Draw all lines between adjacent points
for (size_t i=0; i<pts.size()-1; i++)
    drawLine(pts[i], pts[i+1]);

the above code is UB when the point array is empty because in C++ 0u-1 is a huge positive number.

The reason for which C++ uses an unsigned type for size of containers is because of an historical heritage from 16-bit computers (and IMO given C++ semantic with unsigned types it was the wrong choice even back then).

Tags:

C++