+1 for this. I was just bitten by this last week, when I switched from using a custom container where size() was an int to a std::vector where size() is size_t.
The code was check-all-pairs, e.g.
for (int i = 0; i < container.size() - 1; ++i) {
for (int j = i + 1; j < container.size(); ++j) {
stuff(container[i], container[j]);
}
}
Which worked just fine for int size, but failed spectacularly for size_t size when size==0.I totally should have caught that one, but I just couldn't see it until someone else pointed it out. And then it was obvious, like many bugs.
I recommend using -fsanitize=undefined -fsanitize=integer if you can build with clang - it will print a warning when an unsigned int underflows which catches a terrifying amount of similar bugs the first time it is run (there are a lot of false positives in hash functions, etc though but imho it's well worth using regularly)
yes, but understand that, despite the name, what unsigned models in C / C++ is not "positive numbers" but "modulo 2^N" arithmetic (while signed models the usual arithmetic).
There is no good type that says "always positive" by default in C or C++ - any type which gives you an infinite loop if you do
is not a good type.If you want a "always positive" type use some safe_int template such as https://github.com/dcleblanc/SafeInt - here if you do "x - y" and the result of the computation should be negative, then you'll get the rightful runtime error that you want, not some arbitrarily high and incorrect number
The correct uses of unsigned are for instance for computations of hashes, crypto algorithms, random number generation, etc... as those are in general defined in modular arithmetic