Home > OS >  gcc -Wtype-limits with upper limits
gcc -Wtype-limits with upper limits

Time:01-06

Given this snippet

#include <inttypes.h>

uint8_t test(uint32_t foo) 
{
    if (foo > 0xFFFFFFFF)
    {
        return 0;
    }
    if (foo < 0)
    {
        return 0;
    }
    return 1;
}

compiling with -Wall -Wextra using gcc 12.2 gives only the following warning:

 warning: comparison of unsigned expression in '< 0' is always false [-Wtype-limits]
    9 |     if (foo < 0)
      |             ^

I don't understand why the first line if (foo > 0xFFFFFFFF) does not trigger the same warning.

Trying if (foo > UINT32_MAX) does not trigger any compiler warning.

is it a bug or a feature?

CodePudding user response:

These warnings are not mandated by the language rules, it's up to the compiler vendors to add them, or not. The fact the gcc warns you about the second if can be considered a courtesy. For this reason I believe we can't consider this a bug, unless you can spot this particular feature on the gcc documentation, that could change my view.

I checked clang for these warnings and sure enough it doesn't warn you at all, at least not with those flags:

https://godbolt.org/z/c7hbM3K5d

It's only when you try -Weverything it warns you of both cases:

<source>:5:13: warning: result of comparison 'uint32_t' (aka 'unsigned int') > 4294967295 is always false [-Wtautological-type-limit-compare]
    if (foo > 0xFFFFFFFF)
        ~~~ ^ ~~~~~~~~~~
<source>:9:13: warning: result of comparison of unsigned expression < 0 is always false [-Wtautological-unsigned-zero-compare]
    if (foo < 0)
        ~~~ ^ ~

https://godbolt.org/z/9b9q13rTe

1 for clang in my book.

If you want to see these warnings in your build be sure to use the specific flag (-Wtautological-unsigned-zero-compare and -Wtautological-type-limit-compare), using -Weverything would be too verbose and flag many situations you don't need as mentioned in the comments.


Back to gcc, if you use a wider type for the comparison like for example if (foo > 0xFFFFFFFF0) then you get your warning:

<source>:5:13: warning: comparison is always false due to limited range of data type [-Wtype-limits]
    5 |     if (foo > 0xFFFFFFFF0)
      |             ^

https://godbolt.org/z/Edvz7aq3b

We can assume they forgot to include the max value for uint32_t, it can be an off by one mistake, or it can be that the warning implementation focuses on types rather than values, one can only speculate. You can file a report if you're adamant on having this particular warning working for UINT32_MAX, or at least get to the end of it, and find out what is the reason for this behavior.

  • Related