18

在下面的程序中,第 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 类型检查?

在那里我说了以下内容(我从我的答案中删除了,因为当我运行它时,它没有像我预期的那样出现):

//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 :()
4

4 回答 4

13

-Wall不包括很多选项。 -Wconversion是其中之一,并警告您感兴趣的行为。

http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

于 2011-02-23T19:03:06.007 回答
11

int在为对象赋值的一般情况下char,编译器不知道 是否int超出char.

更仔细地查看实际警告:

warning: overflow in implicit constant conversion

正是在这种特定情况下,char编译器能够警告您将常量转换为常量。同样,如果您将声明更改i为 be const

const int i = 256;

您还会收到警告,因为分配给的值c2是一个常量表达式。

另请注意,该警告有些误导,因为转换在技术上并不“溢出”。算术溢出会在 C++ 中产生未定义的行为。缩小转换(例如intto char,如果int范围大于char)会产生一些实现定义的转换。

于 2011-02-23T18:42:03.473 回答
1

好吧,第 5 行是一个任何编译器都可以直接看到的明显错误,而且总是一个错误。第 4 行至少需要一些数据流分析才能发现错误。也许这不是通过站点上使用的设置来完成的,或者编译器作者可能没有考虑到这一点足够重要而无法弄清楚。

于 2011-02-23T18:44:11.073 回答
1

在 GCC 4.3 之后,-Wconversion已更新 的语义以检测可能更改值的隐式转换,但您也必须启用-Wsign-conversion,否则您将不会收到可能因强制而更改数字符号的代码的警告在有符号和无符号类型之间。

与 Crazy Eddie 所说的相反,在 GCC 4.3(当时尚未发布)-Wconversion之前,一般不会检查隐式类型转换等引入的问题。相反,它会检查您的程序的行为是否与使用旧式 K&R 函数原型时的行为不同。

这不仅意味着它没有对所有隐式类型转换/强制问题给出警告,而且还意味着一些好的代码给出了不必要的警告。当然,你不会得到任何错误,g++因为这样的原型无论如何都不是有效的 C++。

于 2017-09-18T16:42:19.377 回答