A long time ago, I also thought one should use unsigned mostly but I am now in the opposite camp. Unsigned integers in C have semantics for modulo arithmetic. They are suitable if you need this, so for crypto, hashes, or if you only care about bits, etc. IMHO they should not be used for anything else. The reason is that it is very easy to screen for signed overflow bugs exactly because they have undefined behavior, just by turning on a sanitizer. It is also possible to transform overflow to safe traps at run-time where this is important. In contrast, finding unsigned wraparound bugs is extremely hard and can not be done automatically and preventing consequences of such bugs is difficult. Also any kind of index computation may have intermediate results that may be negative, so signed arithmetic is also generally more useful and far easier for people to understand and get right.