Igor Liferenko Igor Liferenko - 2 months ago 13
C Question

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

Answer

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.