读书笔记 effective c++ Item 53 关注编译器发出的警告

许多程序员常常忽略编译器发出的警告。毕竟,如果问题很严重,它才将会变成一个error,不是么?相对来说,这个想法可能在其它语言是无害的,但是在C++中,我敢打赌编译器的实现者对于对接下来会发生什么比你有更好的理解。例如,下面的错误是每个人都时不时会犯的:

1
2
3
4
5
6
7
8
class B {
public:
virtual void f() const;
};
class D: public B {
public:
virtual void f();
};

1. 你对警告的理解可能是错的

你的想法是用D::f重新定义虚函数B::f,但是这里有一个错误:在B中,f是const成员函数,但是在D中,f没有被声明为const。我知道的一个编译器会发出如下警告:

warning: D::f() hides virtual B::f()

太多没有经验的程序员把上面的信息理解为,“当然是D::f把B::f隐藏起来了——这也是它想做的!”但这个理解是错误的。这个编译器正尝试告诉你在B中声明的f没有在D中被重新声明;相反,它被完全隐藏起来了(Item 33中描述了为什么会是这样)。忽略这个编译器警告几乎肯定会导致错误的行为,接下来你会花费大量的时间进行调试来发现编译器已经发现的问题。

2. 忽略警告之前确保你已经理解其意义

在你对特定编译器的警告信息有了一些经验之后,你就会理解不同的信息意味着什么(通常情况下实际的意义和表面上看起来相比会有很大不同。)虽然写出没有编译器警告(即使在最高级别警告下)的程序会是更好的实践,一旦你有了经验,你可能就会选择忽略许多警告。无论如何,在你忽略一个警告之前,确保你已经完全理解了编译器在向你传达什么信息,这很重要。

3. 警告信息因编译器而异

警告信息和编译器是相关的,所以粗心对待你的代码,而依靠编译器来指出你的错误并不可取。例如,前面提到的函数隐藏的代码,换一个编译器可能没有任何回应。

4. 总结

  • 认真对待编译器警告,在编译器支持的最大警告级别下努力写出没有警告的程序。
  • 不要依赖于编译器警告,因为不同的编译器警告会为不同的事情发出警告。将程序移植到一个新的编译器上可能会消除之前你依赖的警告信息。