Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Downcasting a base type

In C++, is it Undefined Behavior if a Base class object is instantiated as a base object, and subsequently downcast to a derived object?

Of course, I would assume it definitely must be undefined behavior, because the Derived class object might have member variables which the base class doesn't. So these variables wouldn't actually exist if the class was instantiated as a base object, which means that accessing them through a Derived class pointer would have to cause Undefined Behavior.

But, what if the Derived class simply provides extra member functions, but doesn't include any further member data? For example:

class Base
{
    public:
    int x;
};

class Derived : public Base
{
    public:
    void foo();    
};

int main()
{
    Base b;
    Derived* d = static_cast<Derived*>(&b);
    d->foo(); // <--- Is this undefined behavior?
}

Does this program cause undefined behavior?

like image 943
Channel72 Avatar asked Dec 16 '22 14:12

Channel72


1 Answers

Yes, it's still undefined behavior, because you're lying to the compiler about the real type of d.

See the standard 5.2.9/8:

An rvalue of type “pointer to cv1 B”, where B is a class type, can be converted to an rvalue of type “pointer to cv2 D”, where D is a class derived (clause 10) from B, if a valid standard conversion from “pointer to D” to “pointer to B” exists (4.10), cv2 is the same cvqualification as, or greater cvqualification than, cv1, and B is not a virtual base class of D. The null pointer value (4.10) is converted to the null pointer value of the destination type. If the rvalue 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 result of the cast is undefined.

The final two sentences say that if the B pointed to by the pointer is not actually part of a D derived class, the cast is undefined behavior.

like image 127
Mark B Avatar answered Dec 31 '22 13:12

Mark B