Static_cast void * char * vs static_cast void ** char **

If I do the following, everything is fine:

char* cp = "abc"; void* vp = NULL; vp = static_cast<void*>(cp);//ok cp = static_cast<char*>(vp);//ok 

But not the following:

 char** cpp = &cp; void** vpp = NULL; vpp = static_cast<void**>(cpp);//error C2440: 'static_cast': //cannot convert from 'char **' to 'void **' cpp = static_cast<char**>(vpp);//error C2440: 'static_cast': //cannot convert from 'void **' to 'char **' 

Please can someone explain to me why other examples are not allowed. Please do not quote the C ++ standard as your answer, because I have already seen the answers that quote it, and I do not understand what they had in mind. I want to understand why other examples do not work (i.e. if you could give an example where it would be dangerous, that would be a big help). Because I do not understand this. For me, both examples are castes. Why does an extra level of indirection matter?

+6
source share
2 answers

A void * pointer can point to “anything”, and it is really designed to convert all pointers to void * , and it is valid to convert all pointers from void * to another type.

However, a void ** is a pointer pointing to the value of void * . And char ** is a pointer to a char * value. These types do not indicate types that can be converted to each other. You can, if you NEED to do this, use void **vpp = reinterpret_cast<void **>(cpp); but it is “unsafe” (you basically tell the compiler “Listen, I know what I'm doing here, just do it”, which may not do what you really expected ...)

+12
source

The limitation is not to violate the type system. The first conversion is in order:

 type *p = ...; void *vp = p; 

As long as you give away this type, you cannot do too much damage to the original value, since there is little to be done with the void object, and all changes in vp are local to the pointer and cannot affect p .

If the second case is allowed:

 type **p = ...; void **vp = p; 

Then great looking and right code can break your application. For instance:

 int *parray[10]; int **p = parray; void **vp = p; *vp = new double(); // now parray[0] is a pointer to a double object, // not a pointer to an int!!! 

The type system was undermined.

That is, the problem is that in the second case there are operations that can be applied to the destination pointer, which can modify the original object and cause errors. Similar examples can be found in other cases (t26) (you can convert int* to const int* , but you cannot convert int** to const int** ...).

+6
source

Source: https://habr.com/ru/post/943883/


All Articles