Search code examples
c++undefined-behaviorstatic-cast

Exactly what is unsafe about this static_cast?


I have written a small example of an unsafe static_cast:

#include <iostream>

class A
{
public:
    virtual int getA(){ return 1; }
};

class B : public A
{
public:
    virtual int getA() { return 2; }
    int getB() { return 3; }
};

int main()
{
    A a;
    B b;
    B* b1 = static_cast<B*>(&a);

    std::cout << "b.getA(): " << b.getA() << std::endl;
    std::cout << "b.getB(): " << b.getB() << std::endl;
    std::cout << "b1->getA(): " << b1->getA() << std::endl;
    std::cout << "b1->getB(): " << b1->getB() << std::endl;
}

The output:

b.getA(): 2
b.getB(): 3
b1->getA(): 1
b1->getB(): 3

I consider it unsafe because I never run the B constructor when creating b1, though accessing it as a B object. Obviously the difference in output shows that b1 does not point to a B object but an A object, as expected.

What other aspects of this is unsafe. Does it involve undefined behavior to even perform the static_cast like this? Otherwise, is it perhaps undefined behavior to access the getA or getB methods?

Anything else? (i don't care about the missing virtual destructor which i don't care about in this example)

Code available on cpp.sh: http://cpp.sh/7sxtz


Solution

  • The static_cast<B *>(&a) causes undefined behaviour.

    C++14 [expr.static.cast]/11:

    [...] If the prvalue of type “pointer to cv1 B” points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the behavior is undefined.