Reputation: 1873
I am looking at a piece of code where there's a c-style cast that puzzles me.
I am fairly familiar with casting, but this one I really can't grasp. So, here it is: I have two classes, say Base and Derived, but Derived does not add any method/attribute. Basically it's just a particular case of Base when one of its attributes (call it M_blockSize) is fixed to 1; however, none of the methods requires a particular implementation nor there is an extension of functionalities. The benefit of such Derived class is not the point of this thread. Let's assume the developers had their good reasons for this.
Anyway, in the piece of code I'm looking something like this happens:
void foo(const Derived& d){...}
[...]
Base b;
foo((Derived&) b);
So, the developers casted the base object into a reference to a derived one. In my understanding, downcasting is done if the concrete type of the "castee" (b) is indeed Derived. Which is not the case here.
However, this is c-style cast, so the compiler is trying a whole bunch of casts and I don't know which one it eventually works.
So, questions:
I hope the question is clear. Thank you for your help.
Upvotes: 2
Views: 1049
Reputation: 110658
The cast in effect here is a static_cast<Derived&>
, governed by the following rule (§5.2.9 Static cast):
An lvalue of type "cv1
B
," whereB
is a class type, can be cast to type "reference to cv2D
," whereD
is a class derived (Clause 10) fromB
, if a valid standard conversion from "pointer toD
" to "pointer to B" exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, andB
is neither a virtual base class ofD
nor a base class of a virtual base class ofD
. The result has type "cv2D
."
The cast "pointer to D
" to "pointer to B
" is a valid standard conversion (§4.10):
A prvalue of type "pointer to cv
D
", whereD
is a class type, can be converted to a prvalue of type "pointer to cvB
", whereB
is a base class (Clause 10) ofD
.
However, just because the cast works, doesn't mean it's okay to do. Note (§5.2.9):
If the object of type "cv1
B
" is actually a subobject of an object of typeD
, the result refers to the enclosing object of typeD
. Otherwise, the result of the cast is undefined.
So this code results in undefined behaviour. You can cast from a base class to any of its derived classes, but you only have define behaviour if it truly is an object of that derived type.
So to answer the questions:
static_cast<Derived&>
.Derived
specific features inside foo
. However, if that's the case, just take a Base&
.Upvotes: 1