C++ 警告:隐式常量转换溢出
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5095434/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Warning : overflow in implicit constant conversion
提问by Nawaz
In the following program, the line 5 does give overflow warningas expected, but surprisingly the line 4 doesn't give any warning in GCC: http://www.ideone.com/U0BXn
在下面的程序中,第 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;
}
I was thinking both lines should give overflowwarning. Or is there something I'm missing?
我在想这两行都应该发出溢出警告。或者有什么我想念的吗?
The topic which led me to do this experiment is this: typedef type checking?
促使我做这个实验的主题是:typedef 类型检查?
There I said the following(which I deleted from my answer, because when I run it, it didn't show up as I had expected):
我在那里说了以下内容(我从答案中删除了它,因为当我运行它时,它没有像我预期的那样显示):
//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 :()
采纳答案by Edward Strange
-Wall
doesn't include many options. -Wconversion
is one of them and warns about the behavior you're interested in.
-Wall
不包括很多选项。 -Wconversion
是其中之一,并警告您感兴趣的行为。
回答by James McNellis
In the general case of assigning an int
value to a char
object, the compiler doesn't know whether the int
is out of range of the char
.
在分配一个的一般情况int
的值char
对象,编译器不知道是否int
是的范围内进行char
。
Look at the actual warning more closely:
更仔细地查看实际警告:
warning: overflow in implicit constant conversion
It is in this specific case, where a constant is being converted to char
that the compiler is able to warn you. Likewise, if you changed the declaration of i
to be const
:
在这种特定情况下,常量被转换为char
编译器能够警告您。同样,如果您将 的声明更改i
为const
:
const int i = 256;
you will also get the warning, because the value being assigned to c2
is a constant expression.
您还将收到警告,因为分配给的值c2
是一个常量表达式。
Note also that the warning is somewhat misleading as the conversion does not technically "overflow." Arithmetic overflow yields undefined behavior in C++. A narrowing conversion (like int
to char
, if int
has a larger range than char
) yields some implementation-defined conversion.
另请注意,该警告在某种程度上具有误导性,因为转换在技术上不会“溢出”。算术溢出在 C++ 中产生未定义的行为。缩小转换(如int
to char
,如果int
范围大于char
)会产生一些实现定义的转换。
回答by Bo Persson
Well, line 5 is an obvious error that any compiler can see directly, and alwaysan error. Line 4 would require at least somedata flow analysis to discover the error. Perhaps this isn't done with the settings used at the site, or perhaps the compiler writers didn't consider this important enough to figure it out.
嗯,第 5 行是一个明显的错误,任何编译器都可以直接看到,而且总是一个错误。第 4 行至少需要一些数据流分析才能发现错误。也许这不是通过站点使用的设置完成的,或者编译器作者可能认为这不够重要而无法弄清楚。
回答by Anonymous
Post GCC 4.3, the semantics of -Wconversion
have been updated to detect implicit conversions that might change a value, but you have to enable -Wsign-conversion
as well, because otherwise you won't get a warning for code that might change the sign of a number due to coercion between signed and unsigned types.
在 GCC 4.3 之后,-Wconversion
已更新的语义以检测可能更改值的隐式转换,但您也必须启用-Wsign-conversion
,否则您将不会收到可能因强制而更改数字符号的代码的警告有符号和无符号类型之间。
Contrary to what Crazy Eddie is saying, prior to GCC 4.3 (which hadn't been released yet at the time) -Wconversion
didn't generically check for problems introduced by implicit type conversion and the like. Rather, it checked whether your program would behave differently than it would have behaved if it had used old-style K&R function prototypes.
与 Crazy Eddie 所说的相反,在 GCC 4.3(当时尚未发布)-Wconversion
之前,通常不会检查隐式类型转换等引入的问题。相反,它会检查您的程序是否会与使用旧式 K&R 函数原型时的行为不同。
This not only meant that it didn't give a warning on all implicit type conversion / coercion problems, but it also meant that some good code gave an unnecessary warning. And of course, you'd get no error with g++
because such prototypes aren't valid C++ anyway.
这不仅意味着它没有对所有隐式类型转换/强制问题给出警告,而且还意味着一些好的代码给出了不必要的警告。当然,你不会出错,g++
因为这样的原型无论如何都不是有效的 C++。