En el contexto de otra pregunta, hubo cierta discusión sobre si estaba permitido (es decir, introduciría o no un comportamiento definido o no definido de implementación) para lanzar int**
a void**
y, posteriormente, asignar un valor al dereferenced void*
. Esto me lleva a mi pregunta sobre la interpretación del estándar C11
6.2.5 (28) Un puntero a anular tendrá los mismos requisitos de representación y alineación que un puntero a un tipo de carácter. …
6.3.2.3 (1) Un puntero para anular se puede convertir en un puntero a cualquier tipo de objeto. Un puntero a cualquier tipo de objeto se puede convertir en un puntero para anularlo y viceversa; El resultado se comparará igual al puntero original.
6.3.2.3 (7) … Cuando un puntero a un objeto se convierte en un puntero a un tipo de carácter, el resultado apunta al byte con la dirección más baja del objeto. …
Mi pregunta es si esto
int* intptr = NULL; void* dvoidptr = &intptr; /* 6.3.2.3 (1) */ *(void**)dvoidptr = malloc(sizeof *intptr); /* using 6.3.2.3 (1) */
¿Cumple con la norma o no? Me parece extraño, pero no puedo encontrar una línea de argumento concluyente por qué no. void*
to void**
está garantizado por 6.3.2.3 y 6.2.5 junto con 6.3.2.3 ayuda con la alineación.
El código no es válido.
Ver el énfasis:
6.3.2.3 (1) Un puntero para anular se puede convertir en un puntero a cualquier tipo de objeto. Un puntero a cualquier tipo de objeto se puede convertir en un puntero para anularlo y viceversa ; El resultado se comparará igual al puntero original .
Está convirtiendo int**
a void*
(fino), y luego a un tipo diferente void**
(no está bien). C no garantiza que pueda convertir con seguridad void*
a otro que no sea el tipo original (aparte de convertir a char *
)
Además, *(void**)dvoidptr
da *(void**)dvoidptr
resultado void*
cuando en realidad hay int*
. ¿Qué sizeof(void*) == 2
si, por ejemplo, sizeof(void*) == 2
y sizeof(int*) == 1
? Puede convertir el puntero void*
a otro tipo, pero no puede reinterpretarlo directamente como otro tipo.