C++编译中常见的一些警告信息及处理办法(未完待续)

来源:互联网 发布:宁夏干部网络学校 编辑:程序博客网 时间:2024/06/05 10:02

1# warning: ... will be initialized after... / ... warning:   when initialized here [1][2]

示例:

 class foo {   //declaration   int i;   int j;           public:     //constructor & its initializer     foo(int val): j(val), i(j) {} };
此示例foo类编译时就将出现上面的警告信息。
C++规定:构造函数初始化列表(constructor's initializer)中,编译器对成员初化的实际顺序是由成员的声明/定义顺序决定的,而与初始化列表中成员的排列顺序无关。在这个示例中,声明的顺序是先i后j,那么按根据这个规定,编译器也会先初始化i,再初始化j。这样上面的示例
  foo(int val): j(val), i(j) {}
在编译过程中首先就是用一个还未初始化的成员j来初始化成员i,这当然会给程序带来bug。所以,编译器友好地给出了上面那条警告信息。 解决办法自然是调整初始化顺序,与声明顺序一致:
  foo(int val): i(val), j(val) {}

Ref.:
[1] C++ Primer 中文版 第4版P389
[2] Stackoverflow.com

2# waring: virtual … was hidden by … [3][4][5]

示例:
 class Base {   public:     virtual int fcn(); };         class Derive:public Base {   public:     // For clearing the warning, uncomment:     //using Base::fcn;     // However, it's not a good idea to do this (using declaration) if this codes are in any header file.     // Or, uncomment:     //int fcn();     int fcn(int); };         int main() {   std::cout<<"Yeah\n";   return 0; }
编译时,如果g++ 或Makefile中加了警告选项:-Woverloaded-virtual,则会出现上面那条的警告信息。 如:
$ g++  overloadBaseMember.cc  -Woverloaded-virtual
overloadBaseMember.cc:33: warning: `virtual int Base::fcn()' was hidden
overloadBaseMember.cc:43: warning:   by `int Derive1::fcn(int)'

这是因为派生类Derive在继承基类Base后,其类作用域内重载了基类中的虚函数fcn,那么在此作用域内原先基类的fcn()函数将被屏蔽/不可见。
解决办法是在派生类中使用using声明(using declaration)来重新声明基类中所有名为fcn的函数(9行),这样使其可见。但此法建议不要用在头文件中;
另一种办法是在派生类Derive中直接重定义Base类中的fcn()函数(12行)。
当然,你要干脆去掉 -Woverloaded-virtual 选项来忽略这类警告,那也是可以的。
至于这样做有什么风险,以及C++为什么要预留这种警告?遗憾本君也未弄清,待后续文章更新中再作理解。(亦盼大侠指点迷津)

Ref.:
[3] C++ Primer 中文版 第4版P501
[4] stackoverflow.com
[5] 当心虚函数重载(overloaded-virtual) by 金庆 

3# warning: statement has no effect

示例:
int i=0, N=100;for( i; i < N; i++)  {}

正确示例:
int i=0, N=100;for( ; i < N; i++) {}  
//orfor(i=0; i<N; i++) {}
要么就必须对for循环的第一个参数做点什么(定义、初始化/赋值),要么就空着不传第一个参数。否则,将出现3#的警告信息。

原创粉丝点击