コンパイラの警告 (レベル 1) C4436
コンストラクターまたはデストラクターで仮想ベース 'class1' から 'class2' への dynamic_cast が、部分的に構築されたオブジェクトで失敗する可能性があります。/vd2 でコンパイルするか、#pragma vtordisp(2) を有効にして 'class2' を定義します
コンパイラは、以下の特徴を持つ dynamic_cast
の操作に遭遇しました。
キャストは、派生クラス ポインターへの基底クラス ポインターから取得されます。
派生クラスは、基底クラスを仮想的に継承します。
派生クラスには、仮想ベースの
vtordisp
フィールドが存在しません。キャストは、派生クラスのコンストラクターまたはデストラクター、あるいは派生クラスをさらに継承するクラスに見られます。
この警告は、dynamic_cast
が部分的に構築されたオブジェクトに対して動作している場合、正しく動作しない可能性があることを示しています。 これは、派生コンストラクター/デストラクターが、さらに派生したオブジェクトのサブオブジェクトで動作している場合に発生します。 警告で指定された派生クラスがそれ以上派生しない場合は、警告を無視できます。
例
次の例では C4436 が生成され、不足している vtordisp
フィールドから発生するコード生成の問題を示します。
// C4436.cpp
// To see the warning and runtime assert, compile with: /W1
// To eliminate the warning and assert, compile with: /W1 /vd2
// or compile with: /W1 /DFIX
#include <cassert>
struct A
{
public:
virtual ~A() {}
};
#if defined(FIX)
#pragma vtordisp(push, 2)
#endif
struct B : virtual A
{
B()
{
A* a = static_cast<A*>(this);
B* b = dynamic_cast<B*>(a); // C4436
assert(this == b); // assert unless compiled with /vd2
}
};
#if defined(FIX)
#pragma vtordisp(pop)
#endif
struct C : B
{
int i;
};
int main()
{
C c;
}