为什么 gcc 不为 int 和 char 产生类型不匹配警告?
Why gcc does not produce type mismatch warning for int and char?
为什么在 gcc 中编译以下代码不会产生任何类型不匹配警告? -1
是 int 类型,f()
期望类型 char:
void f(char c) {}
int main(void)
{
f(-1);
return 0;
}
即使我们明确指定类型,也没有警告:
void f(unsigned char c) {}
int main(void)
{
f((signed int)-1);
return 0;
}
奇怪的是:如果我们指定超出范围的值,则会打印警告:
void f(char c) {}
int main(void)
{
f(65535);
return 0;
}
warning: overflow in implicit constant conversion
gcc 版本 6.1.1
一个int
可以转换为一个char
。 In int
允许在 C 和 C++ 中转换为 char
。
来自 C11 标准:
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.
来自 C++11 标准:
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.
如果char
是有符号类型,它可以很容易地保持值-1。因此,行为是可预测的。 c
在f
中的整数值为-1。当使用 unsigned char
时,c
的值将是一个实现定义的值,但在两个标准下仍然允许。
似乎是 gcc 的 Wconversion 警告选项中的缺陷。
如果启用,此警告选项会警告作业:
int i = c; //where c is of type char
并将变量传递给函数:
f(i); //where i is of type int
但不警告传递整数文字:
f(-1); //where -1 is of type int
根据 C 标准,最后一个示例也应该产生警告。
Gcc 足够聪明,可以识别适合 char 类型的整数文字,并且不会发出警告,而如果使用了不适合的值,它会发出警告。
这是合理的行为,尽管迂腐的用户会排除最后一个示例中的警告,该警告应该通过强制转换为类型 char 来消除。
Gcc 实际上包含一个警告选项,当整数类型的符号通过隐式转换发生更改时发出警告。使用:-Wsign-conversion,你会得到第二个例子的警告。
为什么在 gcc 中编译以下代码不会产生任何类型不匹配警告? -1
是 int 类型,f()
期望类型 char:
void f(char c) {}
int main(void)
{
f(-1);
return 0;
}
即使我们明确指定类型,也没有警告:
void f(unsigned char c) {}
int main(void)
{
f((signed int)-1);
return 0;
}
奇怪的是:如果我们指定超出范围的值,则会打印警告:
void f(char c) {}
int main(void)
{
f(65535);
return 0;
}
warning: overflow in implicit constant conversion
gcc 版本 6.1.1
一个int
可以转换为一个char
。 In int
允许在 C 和 C++ 中转换为 char
。
来自 C11 标准:
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.
来自 C++11 标准:
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.
如果char
是有符号类型,它可以很容易地保持值-1。因此,行为是可预测的。 c
在f
中的整数值为-1。当使用 unsigned char
时,c
的值将是一个实现定义的值,但在两个标准下仍然允许。
似乎是 gcc 的 Wconversion 警告选项中的缺陷。
如果启用,此警告选项会警告作业:
int i = c; //where c is of type char
并将变量传递给函数:
f(i); //where i is of type int
但不警告传递整数文字:
f(-1); //where -1 is of type int
根据 C 标准,最后一个示例也应该产生警告。
Gcc 足够聪明,可以识别适合 char 类型的整数文字,并且不会发出警告,而如果使用了不适合的值,它会发出警告。
这是合理的行为,尽管迂腐的用户会排除最后一个示例中的警告,该警告应该通过强制转换为类型 char 来消除。
Gcc 实际上包含一个警告选项,当整数类型的符号通过隐式转换发生更改时发出警告。使用:-Wsign-conversion,你会得到第二个例子的警告。