https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119011

            Bug ID: 119011
           Summary: -Wsign-compare: Split it into several levels
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: alx at kernel dot org
  Target Milestone: ---

It is usual to compare the return value of a function with -1 (the usual error
code).

Sometimes, functions returning that code do return an unsigned integer type,
such as size_t or time_t.

Programmers currently need to use a cast for the comparison to not trigger
-Wsign-compare:


alx@debian:~/tmp$ cat f.c 
int
main(void)
{
        unsigned long i = 3;

        if (i == -1)
                return 1;

        return 0;
}
alx@debian:~/tmp$ gcc -Wsign-compare f.c 
f.c: In function ‘main’:
f.c:6:15: warning: comparison of integer expressions of different signedness:
‘long unsigned int’ and ‘int’ [-Wsign-compare]
    6 |         if (i == -1)
      |               ^~


But a cast will silence diagnostics, so one usually wants to avoid the cast. 
Indeed, I've seen code placing the cast in the wrong place of this comparison,
and then resulting in bogus code that cannot be diagnosed.

Then, one might consider adding a suffix to the integer literal, to match the
sign.  However, that's also a bug if the width of the literal doesn't match the
width of the variable:

    time_t  t = -1;

    if (t == -1u)

The code above is a bug in platforms where time_t and unsigned int are of
different width.

The only reasonable solution is having the compiler just not warn on comparison
of an unsigned against -1, as long as the -1 will be converted to an unsigned
type (and not the other way around).

So, I propose adding -Wsign-compare=1 and -Wsign-compare=2, with -Wsign-compare
defaulting to one of those (I prefer =1, but I don't care too much).  =1
shouldn't warn about comparison to an unsuffixed literal, as long as the rank
of the literal is lower than the rank of the unsigned variable.

Reply via email to