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
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.