static_cast vs dynamic_cast: undefined behavior

| category: Programming | author: st
Tags:

Do not use static_cast when you cast from a basic class to a derived one. This may lead to undefined behavior. To handle the polymorphism, a virtual inheritance or a multiple inheritance case always use dynamic_cast instead.

The following short example shows the undefined behavior cases. This works with GCC, VC and online C++ shells:

#include <iostream>
using namespace std;

class Employee
{
public:
    virtual void PrintText() { cout << "no data" << endl; }
};

class Manager : public Employee
{
    int data = 1;
public:
    void PrintData() { cout << "data = " << data << endl; }
    void PrintText() override { cout << "text data = " << data << endl; }
};

class CEO : public Employee
{
    int data = 2;
};

int main()
{
    CEO ceo;
    Employee& e = ceo;
    cout << "Test static_cast:" << endl;
    Manager& m1 = static_cast<Manager&>(e);
    m1.PrintData(); // Undefined behavior: prints data = 2
    m1.PrintText(); // Undefined behavior: prints no data
    cout << "Test dynamic_cast:" << endl;
    Manager& m2 = dynamic_cast<Manager&>(e); // std::bad_cast as expected
    m2.PrintData();
    m2.PrintText();
}

The output:

$g++ -o main *.cpp
$main

Test static_cast:
data = 2
no data
Test dynamic_cast:
terminate called after throwing an instance of 'std::bad_cast'
  what():  std::bad_cast
/usr/bin/timeout: the monitored command dumped core
sh: line 1: 143656 Aborted                 /usr/bin/timeout 10s main