Comment interpréter la section 6.3.2.3 partie 7 de la norme C11?

Dans le contexte d’une autre question, il a été demandé si il était permis (c’est-à-dire qu’il introduise ou non un comportement défini ou indéfini par implémentation) de convertir int** en void** et d’assigner par la suite une valeur au void* déréférencé. Cela m’amène à ma question sur l’interprétation de la norme C11

6.2.5 (28) Un pointeur sur un vide doit avoir les mêmes exigences de représentation et d’alignement qu’un pointeur sur un type de caractère. …
6.3.2.3 (1) Un pointeur sur void peut être converti en ou à partir d’un pointeur sur tout type d’object. Un pointeur sur n’importe quel type d’object peut être converti en un pointeur à annuler et inverser; le résultat doit être égal au pointeur d’origine.
6.3.2.3 (7) … Lorsqu’un pointeur sur un object est converti en un pointeur sur un type de caractère, le résultat pointe sur l’octet adressé le plus bas de l’object. …

Ma question est de savoir si cela

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

conforme à la norme ou non? Cela me semble étrange, mais je ne trouve pas d’argument décisif, pourquoi pas. void* to void** est garanti par 6.3.2.3 et 6.2.5 avec l’aide de 6.3.2.3 pour l’alignement.

Le code n’est pas valide.

Voir l’emphase:

6.3.2.3 (1) Un pointeur sur void peut être converti en ou à partir d’un pointeur sur tout type d’object. Un pointeur sur n’importe quel type d’object peut être converti en un pointeur à annuler et inverser ; le résultat doit être égal au pointeur d’origine .

Vous convertissez int** en void* (bien), puis en un autre type void** (pas ok). C ne donne aucune garantie quant à la possibilité de convertir en toute sécurité void* en un type de fichier autre que le type d’origine (mis à part la conversion en caractère char * )

De plus, *(void**)dvoidptr entraîne void* alors qu’en réalité, il y a int* . Et si, par exemple, sizeof(void*) == 2 et sizeof(int*) == 1 ? Vous pouvez convertir le pointeur void* en un autre type, mais vous ne pouvez pas le réinterpréter directement comme un autre type.