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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With