CWARN.MEMBER.INIT.ORDER

未按正确顺序初始化列表成员

类成员以它们进行声明的顺序初始化,而不是以它们显示于初始化列表中的顺序来初始化。为此,应以它们在类中声明的顺序将它们列于初始化列表中。此规则基于 Scott Meyer 的高效 C++ 和 Bjarne Stroustrup 的 C++ 编程语言。

CWARN.MEMBER.INIT.ORDER 检查器会标记初始化列表成员未以类中的声明顺序排列的实例。

漏洞与风险

此缺陷不会导致漏洞,但是在派生类成员之前初始化基类成员非常重要,因此它们应显示在成员初始化列表的开始部分。如果初始化表达式中使用了类数据成员,则可能发生未初始化就使用的情况。此 Klocwork 警告允许重新排序初始化列表,以遵循此规则。

漏洞代码示例

复制
   #include <iostream>
   using namespace std;
 
   class C1{
   public
     int v;
     C1(int v) { this->v = v; cout << "C1::C1: v is set to " << v << endl; }
   };
   class C2{
   public
    C2(const C1& c1) { cout << "C2::C2: c1.v == " << c1.v << endl; }
  };
  class C{
    C2 c2;
    C1 c1;
  public
    C() : c1(100), c2(c1) {}
  };
 
  int main(){
    C c;
    return 0;
  }

在此示例中,C::C() 以错误的顺序初始化了列表 c1 和 c2。虽然看起来一切都正确无误,但是编译器将先初始化 c2,然后再初始化 c1。因此,将得到以下目标输出:

复制
C1::C1: v 设置为 100
C2::C2: c1.v == 100

结果为

复制
C2::C2: c1.v = 32767
C1::C1: v 设置为 100