为什么使用static_cast运算符的不安全强制转换不会崩溃

Why unsafe cast using static_cast operator do not crash?

本文关键字:转换 崩溃 不安全 static 运算符 cast 为什么      更新时间:2023-10-16

请考虑以下示例代码。

#include <iostream>
using namespace std;
class base
{
   public:
       void func()
      {
         cout << "base::func()" << endl;
      }
};
class derived : public base
{
   public:
       void func()
      {
         cout << "derived::func()" << endl;
      }
};
void dummy(base *bptr)
{
  derived *dptr = static_cast<derived*> (bptr);
  dptr->func();
}
int main()
{
   base bob1;
   derived dob1;
   dummy(&dob1); //Line1
   dummy(&bob1); //Line2
}

在第1行中,我将派生类对象的地址传递给函数dummy,该函数将指针指向基类对象。因此函数dummy中的static_cast是安全的。

在第2行中,我将基类对象的地址传递给函数。因此函数dummy中的static_cast是不安全的。

但是当我执行代码时,程序的行为是正常的。我认为,用not safe这个词来说,程序应该在运行时崩溃。但没有发生坠机事件。

这是我得到的输出。

derived::func()
derived::func()

程序在运行时没有崩溃的原因是什么?

因为未定义的行为意味着任何事情都可能发生,而不一定是崩溃。

在我见过的大多数编译器上,调用一个不访问NULL指针上的类成员的非virtual方法是可行的,但它仍然是未定义的。

C++的核心概念之一是未定义行为。当你执行一个导致未定义行为的操作时,例如静态投射一个不指向投射类型对象的指针,你的程序的行为实际上是未定义的:标准没有定义任何特定行为。该平台不需要做任何具体的事情,根据标准,它表现出的任何行为都是可以的。

这种未定义的行为包括默默地做你认为正常的行为。无法保证出现分段故障或任何其他诊断。