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).