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
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 aB
that is actually a subobject of an object of typeD
, the resulting pointer points to the enclosing object of typeD
. Otherwise, the behavior is undefined.