It's a compiler "bug". To elaborate on this:
In general, comparison between signed and unsigned relies on implementation-defined quantities (the sizes/ranges of types). For example USHRT_MAX == -1
is true on common 16-bit systems, and false on common 32-bit systems. The answer by "oblivion" goes into more technical detail about this.
All of your code examples are well-defined and behave the same on all (conforming) systems.
The intent of this warning is twofold:
- to alert you to code that might behave differently on other systems.
- to alert you to code that might not behave as the coder intended.
However, in general. it's not such a simple job for the compiler's static analysis to sort out the first case, let alone the second case which is rather subjective.
IMO the warning, for your code, is a bug because the code is well-defined and there is nothing to warn about.
Personally I don't enable this warning: I'm familiar with the rules for signed-unsigned comparison and prefer to avoid mangling my code to suppress the warning.
Going to the opposite extreme, some people prefer to avoid all signed-unsigned comparisons in their code even when it is well-defined; and they would consider it a bug that the compiler doesn't warn about your first three code examples.
GCC has tended to err on the side of warning too much, but they are in the situation that they can't please everyone.