This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: comparisons..


Andrew Morton wrote:
> >   I'm told that the compiler will warn for this code:
> > 
> >         unsigned int i;
> >         if (i > 5)      /* 'i' is unsigned, '5' is signed, so warn */
> > 
> >   which makes this warning hard to use more than occasionally.

You were told incorrectly.  Try it.  You will not get a warning.
Perhaps you were thinking of the inverse case:

        int i;
	if (i > 5U) ...

Here you WILL get a warning.  The reason for the warning is that
converting a negative int to unsigned produces a large positive value:

	int i = -1;
	if (i > 5U)
		SURPRISE;

is, indeed, surprising.

There are cases where gcc is too stupid to know that a signed-unsigned
comparison is safe.  A typical example is

int bar (int i, unsigned u)
{
    if (i >= 0 && i > u)
	return 3;
    else
	return 2;
}

we get "warning: comparison between signed and unsigned".  This
comparison is safe because we've already assured that i is non-negative
before comparing to u, but for gcc to know that it would need to implement
some kind of range propagation.  To silence the warning you have to write

    if (i >= 0 && (unsigned)i > u)

Toon writes:
> I always wondered whether it would be possible to drop the warning in
> case the signed constant has the same value when interpreted as an
> unsigned value.

Not only is it possible, but this is how gcc has worked for years.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]