Converting from a void*
back to a pointer of the original type is not undefined behavior:
int a = 10;
void* b = (void*)&a;
int* c = (int*)b;
int d = *c; //d == 10 now; this is fine
So, if f2
cast c
back to a void**
before using it, the code would be well-defined. If f2
tries to cast c
to something else (for example, if f2 cast c
to an int*
even though it was given a void**
), that would be undefined behavior.
Pretty much the only exception to this is casting to char*
: that's guaranteed to be ok.
That being said, because you have no type safety when using void*
pointers, if at all possible you should use something else.
This means that this:
void f2(void* c) {
void** b = (void**)c; // Get original void**
void* b_value = *b; // Dereference to get void*
int* int_ptr = (int*)b_value; // Get int* pointer
int value = *int_ptr; // Use it
}
Is safe, if and only if c
represents a pointer to a void*
which itself is a int*
.