条款48: 重视编译器警告
很多程序员日常总是不理睬编译器警告。毕竟,如果问题很严重,就会是个错误,不是吗?这种想法在其它语言中相对来说没什么害处,但在C++中,可以肯定的一点是,编译器的设计者肯定比你更清楚到底发生了什么。例如,大家可能都犯过这个错误:
class B {
public:
virtual void f() const;
};
class D: public B {
public:
virtual void f();
};
本来是想用D::f重新定义虚函数B::f,但有个错误:在B中,f是一个const成员函数,但在D中没有被声明为const。据我所知,有个编译器会这么说:
warning: D::f() hides virtual B::f()
对于这条警告,很多缺乏经验的程序员会这样自言自语,"D::f当然会隐藏B::f ---- 本来就应该是这样!" 错了。编译器想告诉你的是:声明在B中的f没有在D中重新声明,它被完全隐藏了(参见条款50:为什么这样)。忽视这条编译器警告几乎肯定会导致错误的程序行为。你会不停地调试去找原因,而这个错误实际上早就被编译器发现了。
当然,在对某个编译器的警告信息积累了经验之后,你会真正理解不同的信息所表示的含义(唉,往往和它们表面看上去的意思不同)。一旦有了这些经验,你会对很多警告不予理睬。这没问题,但重要的是,在忽略一个警告之前,你一定要准确理解它想告诉你的含义。
只要谈到警告,就要想到警告是和编译器紧密相关的,所以在编程时不要马马虎虎,寄希望于编译器为你找出每一条错误。例如上面隐藏了函数的那段代码,当它通过不同的(但使用很广泛的)编译器时可能不会产生警告。编译器是用来将C++转换成可执行格式的,并不是你的私人保镖。你想得到那样的安全?去用Ada吧。