Search code examples
cgcc-warning

Why gcc does not produce type mismatch warning for int and char?


Why compiling the following code in gcc does not produce any type mismatch warning? -1 is of type int, and f() expects type char:

void f(char c) {}
int main(void)
{
  f(-1);
  return 0;
}

Even if we explicitly specify the types, there is no warning:

void f(unsigned char c) {}
int main(void)
{
  f((signed int)-1);
  return 0;
}

What is curious: if we specify out-of-range value, the warning is printed:

void f(char c) {}
int main(void)
{
  f(65535);
  return 0;
}

warning: overflow in implicit constant conversion

gcc version 6.1.1


Solution

  • Seems like a flaw in gcc's Wconversion warning option.

    If enabled, this warning option warns for assignments:

    int i = c; //where c is of type char
    

    and passing variables to functions:

    f(i); //where i is of type int
    

    but does not warn for passing integer literals:

    f(-1); //where -1 is of type int
    

    According to the C standard the last example should also produce a warning.

    Gcc is smart enough to recognize the integer literal fits into a char type, and doesn't warn, whereas if a value that doesn't fit is used, it does warn.

    This is reasonable behavior, although a pedantic user would except a warning in the last example that should be silenced by a cast to type char.

    Gcc actually includes a warning option to warn when a sign of an integer type is changed through implicit conversion. Use: -Wsign-conversion, and you will get a warning for the second example.