Currently I am working with a legacy c++ code base. In this codebase pointer to objects are converted to void-pointers and then stored in a c-library. Consider the following code:
class interface {
public:
virtual void foo() {
std::cout << "Interface" << std::endl;}
virtual ~interface(){};
};
class debug_interface: public interface {
public:
virtual void foo() {
std::cout << "Debug Interface" << std::endl;}
};
The objects interface
and debug_interface
are allocated on the heap and the address is stored to a void pointer. At some point the pointers are retrieved and then casted back to the base-class interface
. Then the virtual function call is invoked. See
int main(int argc, char *argv[]){
void *handle = reinterpret_cast<void*>(new interface());
void *debug_handle = reinterpret_cast<void*>(new debug_interface());
//void *handle = new interface();
//void *debug_handle = new debug_interface();
interface *foo1 = reinterpret_cast<interface*>(handle);
interface *foo2 = reinterpret_cast<interface*>(debug_handle);
//interface *foo1 = static_cast<interface*>(handle);
//interface *foo2 = static_cast<interface*>(debug_handle);
foo1->foo();
foo2->foo();
return 0;
}
First of all I don't understand, why reinterpret_cast is used. As far as I know, pointer-to-objects can be implicitly converted to void*. Furthermore, to make this cast explicit, a static_cast would be enough, right? But the more important question: Is it really save to cast the pointer debug_handle to interface* ( not to debug_interface*) and invoke the virtual call? According to the c++-standard, (5.2.10) this is undefined behavior:
A pointer to an object can be explicitly converted to a pointer to a different object type.69 When a prvalue v of type “pointer to T1” is converted to the type “pointer to cv T2”, the result is static_cast(static_cast(v)) if both T1 and T2 are standard-layout types (3.9) and the alignment requirements of T2 are no stricter than those of T1. Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value. The result of any other such pointer conversion is unspecified.
The conversion from handle
to foo1
should be ok, but I can again use a static_cast?
Edit My example source code was wrong. debug_interface is a derived class of interface.