如何解释C11标准第6.3.2.3部分第7节?

在另一个问题的上下文中,讨论了是否允许(即,是否会引入实现定义或未定义的行为)将int**void**并随后为取消引用的void*赋值。 这让我想到了对C11标准的解释

6.2.5(28)指向void的指针应具有与指向字符类型的指针相同的表示和对齐要求。 …
6.3.2.3(1)指向void的指针可以转换为指向任何对象类型的指针。 指向任何对象类型的指针可以转换为指向void的指针,然后再返回; 结果应该等于原始指针。
6.3.2.3(7)…当指向对象的指针转换为指向字符类型的指针时,结果指向对象的最低寻址字节。 …

我的问题是这是否

 int* intptr = NULL; void* dvoidptr = &intptr; /* 6.3.2.3 (1) */ *(void**)dvoidptr = malloc(sizeof *intptr); /* using 6.3.2.3 (1) */ 

是否符合标准? 这对我来说似乎很奇怪,但我找不到一个确凿的论据,为什么不呢。 void* to void**由6.3.2.3和6.2.5以及6.3.2.3帮助对齐保证。

代码无效。

看重点:

6.3.2.3(1)指向void的指针可以转换为指向任何对象类型的指针。 指向任何对象类型的指针可以转换为指向void的指针, 然后再返回 ; 结果应该等于原始指针

您正在将int**转换为void* (精细),然后转换为不同类型的void** (不正常)。 C不保证您可以安全地将void*转换为除原始类型之外的任何其他内容(除了转换为char *

另外, *(void**)dvoidptr导致void* ,而实际上有int* 。 例如,如果sizeof(void*) == 2sizeof(int*) == 1怎么办? 您可以 void*指针转换为其他类型,但不能其直接重新解释为其他类型。