在以下程序中,第5行确实按预期提供了溢出警告,但令人惊讶的是第4行在GCC中没有给出任何警告:http://www.ideone.com/U0BXn
int main()
{
int i = 256;
char c1 = i; //line 4
char c2 = 256; //line 5
return 0;
}
我认为两行都应该提供溢出警告。或者有什么我想念的东西?
让我进行此实验的主题是:typedef type checking?
在那里我说了以下(我从我的答案中删除了,因为当我运行它时,它没有像我预期的那样出现):
//However, you'll get warning for this case:
typedef int T1;
typedef char T2;
T1 x = 256;
T2 y = x; //possible overflow warning! (but it doesn't give warning :()
答案 0 :(得分:12)
-Wall
不包含很多选项。 -Wconversion
就是其中之一,并警告你对此感兴趣的行为。
答案 1 :(得分:8)
在为int
对象分配char
值的一般情况下,编译器不知道int
是否超出char
的范围。
更仔细地查看实际警告:
warning: overflow in implicit constant conversion
在这种特定情况下,常量被转换为char
,编译器可以向您发出警告。同样,如果您将i
的声明更改为const
:
const int i = 256;
您也会收到警告,因为分配给c2
的值是一个常量表达式。
另请注意,警告有些误导,因为转换在技术上并不“溢出”。算术溢出在C ++中产生未定义的行为。缩小转化(如int
至char
,如果int
的范围大于char
,则会产生一些实现定义的转化。
答案 2 :(得分:1)
嗯,第5行是一个明显的错误,任何编译器都可以直接看到,总是错误。第4行至少需要某些数据流分析来发现错误。也许这不是使用网站上使用的设置完成的,或者编译器编写者可能认为这不够重要,无法弄明白。
答案 3 :(得分:0)
发布GCC 4.3后,-Wconversion
的语义已更新,以检测可能更改值的隐式转换,但您必须启用-Wsign-conversion
,否则您将不会收到警告对于因签名和无符号类型之间的强制而可能更改数字符号的代码。
与Crazy Eddie所说的相反,在GCC 4.3之前(当时尚未发布)-Wconversion
并未一般性地检查隐式类型转换等引入的问题。相反,它检查了你的程序是否会表现得与它使用旧式K& R函数原型时的行为不同。
这不仅意味着它没有对所有隐式类型转换/强制问题发出警告,而且还意味着一些好的代码会发出不必要的警告。当然,g++
不会出错,因为无论如何这些原型都不是有效的C ++。