Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need a reinterpret_cast to convert Fred ** const to void ** const?

I have a const pointer to a pointer to a Fred and I don't understand why a static_cast isn't sufficient.

typedef struct {
    int n;
} Fred;

Fred *pFred;
Fred **const ppFred = &pFred;
void **const ppVoid = static_cast<void ** const>(ppFred);

Please could someone explain why a reinterpret_cast is needed to convert a pointer to Fred*to a pointer to void* but static_cast is fine to convert pointer to Fred to a pointer to void.

like image 932
DangerMouse Avatar asked Jul 10 '12 09:07

DangerMouse


1 Answers

There's no requirement that a Fred* and a void* have the same size and representation. (I've worked on machines where they didn't, although that was before my C++ days.) When you convert Fred* to void*, you get a new pointer, with a possibly different size and representation, but there is no information about the size and representation of the object the void* points to. You know that it is unknown, and the only way to use this void* is to cast it back to a Fred* (modulo things like cv-qualifiers). When you convert Fred** to void**, you're converting from a pointer to a concrete type (a pointer to a Fred*) to a pointer to another concrete type (a pointer to a void*). And since there's no guarantee that these two concrete types have the same size and representation, the conversion requires a reinterpret_cast. void is a special, non-concrete type, so you can static_cast a pointer to any type to and from a pointer to void. void* is just another concrete pointer type, so casting to and from pointers to it follows the usual rules (and requires a reinterpret_cast).

In many ways, the situation is very much like int and double, where void* plays the role of int (say), and Fred* the role of double. There's no problem static_casting between int and double, but casts between int* and double* require reinterpret_cast.

like image 98
James Kanze Avatar answered Sep 28 '22 11:09

James Kanze