The bug example there, sure, needs a signed type, so you can't blame the type for its wrong usage
I've had more bugs coming from using signed types that I'll not be bothered by writing 'unsigned' ever again
std::size_t i = foo.size();
while (i != 0) {
--i;
...
}It's also worth pointing out the style of loop they give can't be used at all if you are counting down iterators or pointers instead of numbers.
(You can't thus check for int overflow by checking for wraparound, see http://c-faq.com/misc/intovf.html)
Of course, but as you say it yourself: if. It seems a bit too general to abandon unsigned completely because there are cases where it is not appropriate. By that logic there wouldn't be much types one can use at all.
That's useful if your language lacks the ability to return multiple values from a function. That typically was (probably still is on quite a few architectures) the case for languages designed for speed.
Also, in C, int was implicit (see https://github.com/mortdeus/legacy-cc for example source code). So, using int made your programs shorter. That's important if your multi-user system doesn't have much memory (the first PDP-11 that ran Unix had 24 kilobytes of memory), and if you like concise porgrams, as Ritchie apparently did.