如何解释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*) == 2
和sizeof(int*) == 1
怎么办? 您可以将 void*
指针转换为其他类型,但不能将其直接重新解释为其他类型。