不要轻视甚至无视,编译器所报的警告,警告不是错误,但比错误更加凶险。也即,我们要追求没有警告的程序。
本文,将以编译器经常会报的一个异常:warning C4018: “>=”: 有符号/无符号不匹配 为例说明忽视警告常会伴随一些古怪的结果发生。
当带正负号的i
与不带正负号的类型比较时,i
会自动转型为无正负号值。
故当一个有符号数与无符号的0比较(一个无符号数永远大于等于0),并用作循环是否执行的判断依据时,将很有可能陷入死循环,无论循环体的内部是否对该有符号数执行减法的操作。
for (size_t i = 5; i >= 0; --i)
std::cout << i << " ";
std::cout << std::endl;
上述代码陷入死循环中,显然是循环退出的条件i >= 0
永远无法满足,这又是为什么呢,i
不是一直在减吗?不要忘记,i
的类型为size_t
,也即unsigned int
,无符号整数,而无符号的0减去1得到的结果一定不是-1,
std::cout << size_t(0)-1 << std::endl;
// 4294967295
永远无法满足循环退出的条件;
据说Java语言的基本数据类型都是有符号的,所以Java中不存在该问题)