I work with a lot of calculation code written in C++ with high performance and low memory overhead in mind. It uses STL containers (mostly vector
) a lot, and iterates over that containers almost in every single function.
The iterating code looks like this:
for (int i = 0; i < things.size(); ++i)
{
// ...
}
but it produces the signed/unsigned mismatch warning (C4018 in Visual Studio).
Replacing int
with some unsigned
type is a problem because we frequently use OpenMP pragmas, and it requires the counter to be int
.
I'm about to suppress the (hundreds of) warnings, but I'm afraid I've missed some elegant solution to the problem.
On iterators. I think iterators are great when applied in appropriate places. The code I'm working with will never change random-access containers into list
or something (so iterating with int i
is already container agnostic), and will always need the current index. And all the additional code you need to type (iterator itself and the index) just complicates matters and obfuscates the simplicity of the underlying code.
It's all in your things.size()
type. It isn't int
, but size_t
(it exists in C++, not in C) which equals to some "usual" unsigned type, i.e. unsigned int
for x86_32.
Operator "less" (<) cannot be applied to two operands of different sign. There's just no such opcodes, and standard doesn't specify, whether compiler can make implicit sign conversion. So it just treats signed number as unsigned and emits that warning.
It would be correct to write it like
for (size_t i = 0; i < things.size(); ++i) { /**/ }
or even faster
for (size_t i = 0, ilen = things.size(); i < ilen; ++i) { /**/ }