简体   繁体   中英

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM