How does gcc handle -Wtype limits?

I am testing a small piece of code with the gcc 4.4.5 and -Wtype-limits .

 #include <assert.h> #include <limits.h> #include <stdint.h> int main(void) { /* With other values of v, the behavior of the compiler is the same. */ uint16_t v = 0; assert((unsigned int)INT_MAX < (unsigned int)v); /* l. 7 */ return 0; } 

Then the compiler gives me the following warning:

main.c:7: warning: comparison is always false due to limited range of data type

However, as far as I know, INT_MAX can be equal to +32767 (from C11 (n1570), Β§ 5.2.4.2.1 Dimensions of integer types <limits.h> ). In this case, the variable v will be able to hold the value of INT_MAX+1 , and the expression in assert will be evaluated as 1 .

Therefore, I see two problems:

  • GCC takes my architecture into account, because actually INT_MAX not +32767 . In this case, this will reduce the benefits of -Wtype-limits for me.
  • This is mistake.

What makes me think about the second option is the following code, which does not give any warnings with the same parameters.

 #include <assert.h> #include <limits.h> #include <stdint.h> int main(void) { assert((unsigned int)INT_MAX < (unsigned int)UINT16_MAX); return 0; } 

So what is the correct answer?

PS: By the way, I have to apologize for my old version of gcc. The behavior of future releases may be different.

+4
source share
1 answer

GCC takes into account the actual known type limits. He knows that int has a width of more than 16 bits in your case, so it warns.

You will not receive a warning for

 #include <assert.h> #include <limits.h> #include <stdint.h> int main(void) { assert((unsigned int)INT_MAX < (unsigned int)UINT16_MAX); return 0; } 

as the standard says in 7.20.2 (2):

Each instance of any specific macro is replaced with a constant expression suitable for use in preprocessor #if directives , and this expression must be of the same type as the expression that is an object of the corresponding type converted in accordance with whole promotions.

so with a 32-bit wide int s, the UINT16_MAX macro is int , so the limits of the types involved do not guarantee that the comparison is always false (or true).

+4
source

All Articles