Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does gcc handle -Wtype-limits?

Tags:

c

types

gcc

I'm testing a small code snippet with gcc 4.4.5 and -Wtype-limits option on.

#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 throws 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 may be equal to +32767 (from C11 (n1570), § 5.2.4.2.1 Sizes of integer types <limits.h>). In that case, the variable v would be able to hold the value INT_MAX+1, and the expression in assert would be evaluated to 1.

Therefore, I can see two issues:

  • GCC takes in account my architecture, because, in fact, INT_MAX is not equal to +32767. In that case, it would reduce the benefits of -Wtype-limits for me.
  • It is a bug.

What it makes me think about the second option is the following code, which doesn't produce any warning with the same options.

#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 because of my old version of gcc. Maybe the behavior of the next releases is different.

like image 573
md5 Avatar asked Oct 04 '22 07:10

md5


1 Answers

GCC does take into account the actual known limits of the types. It knows that int is more than 16 bits wide in your case, so it warns.

You get no 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;
}

because the standard says in 7.20.2 (2):

Each instance of any defined macro shall be replaced by a constant expression suitable for use in #if preprocessing directives, and this expression shall have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions.

so with 32-bit wide ints, the macro UINT16_MAX is an int, hence the limits of the involved types don't guarantee that the comparison is always false (or true).

like image 143
Daniel Fischer Avatar answered Oct 13 '22 11:10

Daniel Fischer