这个C++程序是否会调用未定义的行为?

Des*_*tor -6 c++ inheritance static-cast undefined-behavior language-lawyer

我正在阅读有关static_cast运算符的内容.

考虑以下示例:

#include <iostream>
class B { };
class D : public B 
{
    public:
        void fun()
        {
            std::cout<<"fun() is called\n";
        }
};
void f(B* pb,D* pd)
{
    D* pd2=static_cast<D*>(pb);
    B* pb2=static_cast<B*>(pd);
    pd2->fun();
}
int main()
{
    B b;
    D d;
    f(&b,&d);
}
Run Code Online (Sandbox Code Playgroud)

它说:

在下面的示例中,行D*pd2 = static_cast(pb); 是不安全的,因为D可以有不在B中的字段和方法.但是,行B*pb2 = static_cast(pd); 是一个安全的转换,因为D总是包含所有的B.

与dynamic_cast相反,没有对pb的static_cast转换进行运行时检查.pb指向的对象可能不是D类型的对象,在这种情况下使用*pd2可能是灾难性的.例如,调用作为D类成员但不是B类成员的函数可能会导致访问冲突.

我在gcc 4.8.1和MSVS 2010上尝试了它并获得输出fun()被调用.那么这个程序会调用未定义的行为吗?我的程序可以在运行时崩溃吗?C++标准对此有何看法?如果我理解错误,请纠正我.

Lig*_*ica 11

是的,当然是.

您通过强制转换来调用D仅对象的对象的成员函数.BB*D*

它"似乎工作",因为所涉及的功能不会尝试访问任何实际数据,因此,没有内存访问权限供您的计算机在运行时注意和抱怨.


事实上,我们甚至不需要费心去讨论函数调用是否具有未定义的行为; 演员本身很糟糕:

[C++14: 5.4.9/11]: 类型为"指向cv1的 指针"的prvalue B,其中B是一个类类型,可以转换为类型为"指向cv2的 指针"的prvalue D,其中D是一个派生类(第10条)B,如果是从"指针到"的有效标准转换D"到'指针B’的存在(4.10) ,CV2是相同的CV-资格作为,或更大的CV-资格比,CV1,并且B既不是虚基类的D,也不是基类的虚拟基类的D.空指针值(4.10)将转换为目标类型的空指针值.如果"指向cv1的 指针B" 类型的prvalue指向B实际上是类型对象的子对象D,则生成的指针指向类型的封闭对象D.否则,行为未定义.