Reputation: 6337
What should I do about the "signed/unsigned mismatch" warning in C++ code like this:
for (int i = vector.size() - 1; i >= 0; --i) // OK
{
if (i < vector.size() / 2) // warning C4018: '<': signed/unsigned mismatch
// ...
}
(A contrived example, but it demonstrates the problem.)
How do I deal with "signed/unsigned mismatch" warnings (C4018)? says to use size_t
for the loop variable, but this doesn't work for a decrementing loop terminating at 0. It compiles without warning, but the integer overflows (or is it underflows?) at runtime and becomes 4294967295.
Upvotes: 2
Views: 2936
Reputation: 275600
Me I would write an index range-for adapter.
And write backwards, which adapts a range to iterate in reverse.
This gives us:
for(auto i:backwards(indexes_into(container))){
the result is less error prone, as efficient, and clearer intention at point of use (so long as you trust your utility code).
Solutions to both exist in boost, rangesv3, and various of my SO posts.
Upvotes: 0
Reputation: 320571
Firstly, learn a few well-established idioms that'd allow you to write decrementing cycles using unsigned
types. This is an absolutely essential skill in C and C++. E.g.
for ([some unsigned type] i = N; i-- > 0; )
{
// Process i-th element
}
or
for ([some unsigned type] i = N; i > 0; )
{
--i;
// Process i-th element
}
(Note, that the initial value of i
is N
, not N - 1
.)
Or you can even use a "more natural" approach
for ([some unsigned type] i = N - 1; i != -1; --i)
{
// Process i-th element
}
Secondly, start using the proper unsigned type for vector indexing. In your case
for (auto i = vector.size() - 1; i != -1; --i)
or
for ([your vector type]::size_type i = vector.size() - 1; i != -1; --i)
That will solve your warning issue.
Alternatively, you can choose a "loser's way out" and just suppress the warning by using an explicit cast
if ((unsigned) i < vector.size() / 2)
or just do #pragma warning(disable: 4018)
.
Upvotes: 7
Reputation: 13087
or alternatively:
for(size_t j = 0; j < vector.size(); j++){
size_t i = vector.size() - 1 - j;
...
}
Upvotes: 1
Reputation: 34002
There are several options you could do:
If you use a vector use an iterator for traversing it:
for (auto it = vector.rbegin(); it != vector.rend(); ++it)
Or use a different for statement:
for (size_t i = vector.size(); i-- > 0; )
I also have seen for(size_t i = myArray.size() - 1; i != (size_t)-1; i--)
(cf. What's the best way to do a backwards loop in C/C#/C++?)
Upvotes: 3
Reputation: 3049
Use the proper type (auto
, std::size_t
, std::vector<...>::size_type
) and iterate from vector.size()
down to 0
(and not from vector.size() - 1
down to -1
) instead:
for (std::size_t i = vector.size(); i > 0; --i)
{
if (i < vector.size() / 2 + 1)
// ...
}
Upvotes: 0