Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing base class members with incorrect downcast in C++

Is the following C++ code correct?

struct Base { int x; };
struct Derived : Base { int y; }
Base * b = new Base;
Derived * d = static_cast<Derived *>(b);
//below we access only d->x, but not d->y
std::cout << d->x;

If not, what exactly is wrong? What C++ standard say about this? At least I have not seen it ever crashed.

like image 407
Koban Avatar asked Dec 12 '25 14:12

Koban


1 Answers

This is reasonably straightforward in [expr.static.cast]/11 (emphasis mine):

A prvalue of type “pointer to cv1 B”, where B is a class type, can be converted to a prvalue of type “pointer to cv2 D”, where D is a class derived from B, if cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If B is a virtual base class of D or a base class of a virtual base class of D, or if no valid standard conversion from “pointer to D” to “pointer to B” exists ([conv.ptr]), the program is ill-formed. The null pointer value is converted to the null pointer value of the destination type. 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.

You don't have a subobject of a Derived, so it's undefined behaviour.


Note there are no special cases for lvalue or xvalue pointers, and /8 mentions that the operand undergoes an lvalue-to-rvalue conversion.

like image 172
chris Avatar answered Dec 14 '25 02:12

chris