Reputation: 19065
In the first comment to Python C Module - Malloc fails in specific version of Python, @user694733 mentions that casting char**
to void**
is not valid. I read Invalid conversion from Foo** to void** - why is implicit type conversion allowed to void* but not to void**? and http://c-faq.com/ptrs/genericpp.html but there is a reference to standard, but no real example, in which case this might be incorrect, leading to errores . Thinking of e.g. void**
to double**
or vice versa, is there a case where it can go wrong? Why (technically, not just because it is UB)?
Upvotes: 4
Views: 722
Reputation: 757
but there is a reference to standard, but no real example, in which case this might be incorrect, leading to errors
This is not accurate. Page http://c-faq.com/ptrs/genericpp.html which you mentioned points to another page http://c-faq.com/null/machexamp.html which contains an example of machines with different pointer sizes for different types:
The Eclipse MV series from Data General has three architecturally supported pointer formats (word, byte, and bit pointers), two of which are used by C compilers: byte pointers for char * and void *, and word pointers for everything else. For historical reasons during the evolution of the 32-bit MV line from the 16-bit Nova line, word pointers and byte pointers had the offset, indirection, and ring protection bits in different places in the word. Passing a mismatched pointer format to a function resulted in protection faults. Eventually, the MV C compiler added many compatibility options to try to deal with code that had pointer type mismatch errors.
Upvotes: 1
Reputation: 308111
The biggest practical problem is with multiple inheritance. When you use a pointer to a class with multiple base classes, the actual value of the pointer will depend on the type of the pointer, and the compiler inserts fix-up code to adjust it when you assign from one pointer type to another. When you have a pointer to the pointer, the compiler no longer has the opportunity to do those fixups, so the operation is disallowed by the standard.
Upvotes: 1
Reputation: 208323
If that was allowed, it would create a loop hole in the type system:
T* ptr;
void **vptr = &ptr; // &ptr is of type T**
int value;
*vptr = &value; // &value is int*, can be converted to void*
At this point, ptr
, which is according to the type system a pointer to T
, is pointing to value
that is an int
. While the language allows you to circumvent the type system, you have to explicitly request it. Implicit conversions are designed to avoid this type of issues.
Upvotes: 11