CWARN.MEMBER.INIT.ORDER

初期化リストのメンバーの順序が正しくありません。

クラスメンバーは、初期化リストの順序ではなく、それらが宣言された順序で初期化されます。このため、クラスメンバーは、クラス内で宣言される順序で初期化リストに記述する必要があります。この規則は、Scott Meyer の Effective 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 is set to 100
C2::C2: c1.v == 100

結果は次のようになります。

コピー
C2::C2: c1.v = 32767
C1::C1: v is set to 100

外部参考資料