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

青春壹個敷衍的年華 提交于 2019-12-12 17:11:44

问题


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


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




回答2:


An int can be converted to a char. In int is allowed to be converted to a char in both C and C++.

From the C11 Standard:

6.3.1.3 Signed and unsigned integers

1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.

2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

From the C++11 Standard:

4.7 Integral conversions

1 A prvalue of an integer type can be converted to a prvalue of another integer type. A prvalue of an unscoped enumeration type can be converted to a prvalue of an integer type.

2 If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer ...

3 If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.

If char is a signed type, it can easily hold the value -1. Hence, the behavior is predictable. The integral value of c in f will be -1. When unsigned char is used, the value of c will be an implementation-defined value but it is still allowed under both the standards.



来源:https://stackoverflow.com/questions/39695149/why-gcc-does-not-produce-type-mismatch-warning-for-int-and-char

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!