Search code examples
ccomparisonunsigned-integersignedness

C comparison 'x < 0' where type of 'x' is arbitrary, i.e. might be unsigned


GIVEN:

A type defined as TheValueT that may be arbitrarily configured, e.g. as uint8_t or int64_. Let there be some code:

TheValueT   x = ...;

... do something to 'x' ...

if( x < 0 ) {
   /* Do something. */
}

PROBLEM:

It happens that if TheValueT is defined as an unsigned type, the compiler complains about 'condition always true because of limited range of type ...'.

QUESTION:

How can the compiler warning be avoided whilst letting TheValueT still be of arbitrary integer type? The solution should be applicable to the widest range of C compilers.


Solution

  • A simple and safe way to write your test would be this:

    TheValueT x = /* ... */;
    
    if (x < 1 && x != 0) {
        // do something
    }
    

    It is possible that a clever enough compiler would warn about that anyway, but the same is true of any correct alternative that can be written to cover all possible integer types (including extension types). That does work around the warning in my implementation.

    No alternative requiring an arithmetic computation involving the value of x definedly produces the correct result in all cases -- these run into problems with values of x at the extremes of its or other types' ranges.

    This does assume that TheTypeT must be an integer type. If floating types are a possibility, too, then your best bet may be to just live with the warning, or to use a compiler flag to turn off that particular warning during production builds.