Suppose we have the following code:
#include <iostream>
struct A
{
virtual void f() {
std::cout << "A::f()" << std::endl;
}
};
struct B: A
{
void f() {
std::cout << "B::f()" << std::endl;
}
};
void to_A(void* voidp) {
A* aptr = static_cast<A*>(voidp);
aptr->f();
}
void to_B(void* voidp) {
B* bptr2 = static_cast<B*>(voidp);
bptr2->f();
}
int main() {
B* bptr = new B;
void* voidp = bptr;
to_A(voidp); // prints B::f()
to_B(voidp); // prints B::f()
}
is this code guaranteed to always work as in the code comments or is it UB? AFAIK it should be ok, but I’d like to be reassured.
EDIT
Ok, so it seems there’s a consensus that this code is UB, as one can only cast to the exact type. So, what if the main() changes to:
int main() {
B* bptr = new B;
to_A(static_cast<A*>(bptr)); // still prints B::f()
to_B(bptr); // still prints B::f()
}
is it still UB?
Your first code example invokes undefined behaviour.
You can use a
static_castto reverse a standard conversion of pointer to object type to pointer tovoidbut the result is only guaranteed if the value of the pointer tovoidbeing converted back to the original object type is the result of the standard conversion of a pointer to the original type to pointer tovoid.Your second code example is OK because you only reverse conversions from pointer-to-type to pointer-to-void by casting back to the original type that the conversion was made from. This is guaranteed in 5.2.9 [expr.static.cast] of the standard (C++03).