为什么char **(或任何T **)无效**无效?

在对Python C模块的第一条评论中–Malloc 在特定版本的Python中失败 ,@ user694733提到将char**void**无效。 我读了从Foo **到void **的无效转换 – 为什么隐式类型转换允许void *但不是void **? 和http://c-faq.com/ptrs/genericpp.html但有一个标准的引用,但没有真正的例子,在这种情况下,这可能是不正确的,导致错误。 考虑例如void** double**或反之亦然,是否有可能出错的情况? 为什么(从技术上讲,不只是因为它是UB)?

但是有一个标准的引用,但没有真正的例子,在这种情况下,这可能是不正确的,导致错误

这不准确。 您提到的页面http://c-faq.com/ptrs/genericpp.html指向另一页http://c-faq.com/null/machexamp.html ,其中包含不同指针大小的机器示例类型:

Data General的Eclipse MV系列有三种架构支持的指针格式(字,字节和位指针),C编译器使用其中两种:char *和void *的字节指针,以及其他所有字的指针。 由于历史原因在从16位Nova线演变32位MV线期间,字指针和字节指针在字中的不同位置具有偏移,间接和环保护位。 将不匹配的指针格式传递给函数会导致保护错误。 最终,MV C编译器添加了许多兼容性选项,以尝试处理具有指针类型不匹配错误的代码。

如果允许,它将在类型系统中创建一个循环孔:

 T* ptr; void **vptr = &ptr; // &ptr is of type T** int value; *vptr = &value; // &value is int*, can be converted to void* 

此时, ptr ,根据类型系统指向T的指针,指向的valueint 。 虽然该语言允许您绕过类型系统,但您必须明确请求它。 隐式转换旨在避免此类问题。

最大的实际问题是多重inheritance。 当您使用指向具有多个基类的类的指针时,指针的实际值将取决于指针的类型,并且当您从一个指针类型分配给另一个指针类型时,编译器会插入修正代码来调整它。 当您有指向指针的指针时,编译器不再有机会执行这些修正,因此标准不允许该操作。