JSF.USE.STATIC.NON_LOCAL

変換単位が異なる非ローカル静的オブジェクトが特別な順序で初期化されると仮定してはなりません。

理論的根拠

順序の依存性は検出が困難なバグにつながります。

脆弱性とリスク

非ローカル静的オブジェクトの初期化の順序は問題を起こす可能性があります。たとえば、コンストラクタが実行される前に非ローカル静的オブジェクトが初期化されない場合、そのオブジェクトをコンストラクタで使用できない可能性があります。現時点では、個別のコンパイル単位で定義される非ローカル静的オブジェクトの初期化の順序は規定されていません。これは、検出が困難なエラーにつながる可能性があります。

軽減と防止

この問題は、各非ローカル静的オブジェクトを、それらがローカル静的オブジェクトに置き換わる独自の関数に移すことで解決できることがあります。関数に含まれるローカル静的オブジェクトへの参照がその関数によって返される場合、クライアントは初期化順序の問題に直面することなく、関数を介してオブジェクトにアクセスできます。関数呼び出しのオーバーヘッドをなくす方法として、関数をインライン化できます。このほか、起動時にメモリプールまたはスタックにオブジェクトを割り当てることもできます。

例 1

コピー
  // file 1
  static int32 x = 5;
  // file 2
  static int32 y = x + 1; // Bad assumption.The compiler might not have initialized
                          // static variable x.

これを解決するには、静的非ローカルオブジェクトを静的ローカルオブジェクトに置き換えます。これは、静的ローカルオブジェクトに作成時間 (囲み関数による最初の時間) が正確に定義されているためです。

例 2

コピー
  inline Resource& the_resource()
  {
      static Resource r;
      return r;
  }

これで、クライアントは、Resource オブジェクト r と、同様に定義された他のローカル静的オブジェクトの初期化の順序を考慮することなく、いつでも Resource オブジェクト r を the_resource() として参照できます。