コンパイラの警告 (レベル 4) C4437

仮想基底 'class1' から 'class2' への dynamic_cast は、一部のコンテキストで失敗する可能性があります。/vd2 でコンパイルするか、#pragma vtordisp(2) を有効にして 'class2' を定義してください

既定では、この警告はオフに設定されています。 詳細については、「 既定で無効になっているコンパイラ警告 」を参照してください。

コンパイラは、以下の特徴を持つ dynamic_cast の操作に遭遇しました。

  • キャストは、派生クラス ポインターへの基底クラス ポインターから取得されます。

  • 派生クラスは、基底クラスを仮想的に継承します。

  • 派生クラスには、仮想ベースの vtordisp フィールドが存在しません。

  • 派生クラスまたは、派生クラスをさらに継承するクラスのコンストラクターまたはデストラクターにキャストが見つかりません (それ以外の場合、コンパイラの警告 C4436 が発生します)。

この警告は、dynamic_cast が部分的に構築されたオブジェクトに対して動作している場合、正しく動作しない可能性があることを示しています。 この状況は、外側の関数が、警告で挙げられている派生クラスを継承するクラスのコンストラクターまたはデストラクターから呼び出されると発生します。 警告で挙げられている派生クラスがそれ以上派生しないか、オブジェクトの作成または破棄中に外側の関数が呼び出されない場合は、この警告を無視してもかまいません。

次の例では C4437 が生成され、不足している vtordisp フィールドから発生するコード生成の問題を示します。

// C4437.cpp
// To see the warning and runtime assert, compile with: /W4
// To eliminate the warning and assert, compile with: /W4 /vd2
//       or compile with: /W4 /DFIX
#pragma warning(default : 4437)
#include <cassert>

struct A
{
public:
    virtual ~A() {}
};

#if defined(FIX)
#pragma vtordisp(push, 2)
#endif
struct B : virtual A
{
    B()
    {
        func();
    }

    void func()
    {
        A* a = static_cast<A*>(this);
        B* b = dynamic_cast<B*>(a);     // C4437
        assert(this == b);              // assert unless compiled with /vd2
    }
};
#if defined(FIX)
#pragma vtordisp(pop)
#endif

struct C : B
{
    int i;
};

int main()
{
    C c;
}

関連項目

dynamic_cast 演算子
vtordisp
コンパイラの警告 (レベル 1) C4436