编译器警告(等级 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