web-dev-qa-db-ja.com

clangの「exit-time destructor」警告に対処する方法は?

次の場合、C++ 11コードで「宣言には終了時間デストラクタが必要です」というclang警告が表示されます。

static const std::map<int, const someStruct> mymap = {
    {1, {
        "A",
        "B",
        "C"
    }},
    {2, {
        "D",
        "E",
        "F"
    }}
};

Googleが理解している限り、「すでに解放された変数」による終了時のクラッシュを防ぐために、確定的な方法でmain()とstaticを破棄するには、「終了時デストラクタ」が必要です。そうですか?誰かがそれをよりよく説明できますか?

プラス:私はそれについて何ができますか(警告を無効にしたくない)?上記のコードは、1つのスレッドのコンテキスト内でのみ使用されます。

これがChromiumがこれらのケースを処理する方法であるように見えます。それは私の場合にも正しい方法でしょうか?

#define CR_DEFINE_STATIC_LOCAL(type, name, arguments) \
  static type& name = *new type arguments

(ソース: https://chromium.googlesource.com/chromium/src/+/32352ad08ee673a4d43e8593ce988b224f6482d3/base/basictypes.h

36
Lars Schneider

グローバルおよび関数の静的オブジェクトは、アプリケーションの終了時にデストラクタが呼び出されます。これらのデストラクタは「出口時間デストラクタ」です。そして、それらが構築されたのとは逆の順序で呼び出されます。

あなたが言ったように、これらのデストラクタのいくつかがすでに破壊されたオブジェクトに触れると、プログラムがクラッシュする可能性があります。また、終了時にデストラクタを実行すると、プログラムの終了が遅くなり、ほとんどの場合、プログラムの正確さのためにデストラクタは必要ありません(プログラムが終了すると、すべてのメモリが解放されます)。

警告は単に、終了時に実行されるデストラクタがあることを示しています。

提案した修正により、オブジェクトがヒープ割り当てされます。これにより、プログラムの終了時にオブジェクトが自動的に破棄されることはありません。あなたの場合、これで十分でしょう。

18
yiding