Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I Have to reinterpret_cast Pointer Pointers?

So this static_cast code is totally legal:

int n = 13;
void* pn = static_cast<void*>(&n);
void** ppn = &pn;

Yet this has to be made into a reinterpret_cast to compile:

int n = 13;
int* foo = &n;
void** bar = static_cast<void**>(&foo);

If I don't change it I get the error:

error C2440: static_cast: cannot convert from int ** to void ** note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

So I take it the issue is "the types are unrelated". Yet I still don't understand, if it's OK when going from an int* to void* how can they be unrelated as a int** and a void**?

like image 577
Jonathan Mee Avatar asked Jan 27 '23 10:01

Jonathan Mee


1 Answers

int is in no way related to void. The same goes for int** and void** and so they cannot be converted using static_cast.

void* however, is special. Any data pointer type (including int*) can be static_cast into void* and back, despite no type being related to void (even further, the conversion to void* doesn't need a cast, as it is implicit). int* doesn't have this property, nor does void** and nor does any other pointer besides void*.


The additional freedoms that have been granted to void* come with additional restrictions. void* cannot be indirected, nor can it be used with pointer arithmetic. These restrictions are only possible because there can never be an object of type void. Or from opposite point of view, objects of void cannot exist because of these restrictions.

void** cannot be given those freedoms, because it cannot be given the same restrictions. It cannot be given those restrictions because void* objects do exist and they need to exist. If we couldn't indirect or iterate void**, then we couldn't use arrays of void* for example.

like image 138
eerorika Avatar answered Feb 06 '23 05:02

eerorika