À quel point la conversion de vide ** en caractère ** est-elle dangereuse?

Nous soaps donc que la norme ne force pas les tailles de pointeurs à être égales. ( ici et ici ) (et ne parle pas de pointeurs de fonction)

Je me demandais comment, en réalité, cela pouvait être un problème. Nous soaps que void * peut contenir n’importe quoi, donc si la taille du pointeur est différente, ce sera la taille la plus grande. Dans ce cas, atsortingbuer un void ** à un caractère char ** synonyme de problèmes.

Ma question est la suivante: à quel point serait-il dangereux de supposer que void * et char * ont la même taille? Y a-t-il réellement une architecture où ce n’est pas vrai?

De plus, le format 16 bits n’est pas ce que je veux entendre! 😉

void * et char * ont la même taille.

void ** n’est pas garanti d’avoir la même taille que char ** (mais très similaire à votre implémentation, ils l’auront).

(C99, 6.2.5p27) “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 […] Les pointeurs sur d’autres types ne doivent pas nécessairement avoir les mêmes exigences de représentation ou d’alignement.”

L’affectation de pointeurs de types d’object différents est autorisée tant qu’aucune exigence d’alignement n’est violée: L’affectation impliquera une conversion de type (implicite), de sorte qu’elle est aussi (peu) problématique que l’atsortingbution d’un float à un int – elle fonctionne dans la plupart des cas, mais est autorisé à exploser lorsqu’une conversion significative est impossible.

char * et void * ont des exigences d’alignement compatibles par spécification, donc assigner un caractère char ** à une variable void ** (et vice versa) n’est jamais problématique. Ils ont même une représentation compatible, ce qui signifie, en principe, accéder à un caractère char * via une expression de type void * – par exemple en supprimant un caractère void ** qui pointe en fait sur un caractère char * – fonctionnera comme prévu dans la plupart des cas. Bien entendu, l’inverse (accéder à un void * en déréférencant un caractère char ** ) est également vrai.

Par exemple, le spécificateur de conversion p de printf() attend un void * et la transmission d’un type de pointeur arbitraire est un comportement indéfini. Cependant, dans le cas de char * , cela devrait fonctionner même sur des architectures exotiques (par exemple avec des représentations de pointeur différentes) tant que l’implémentation est conforme à la norme C.

Une parsing de repliement risque de poser problème: en raison des règles de dactylographie efficaces, un void ** et un caractère char ** ne peuvent pas créer un alias. Si le programmeur ne respecte pas cette promesse, des choses étranges peuvent se produire. On doit se rendre compte qu’en raison de la frappe efficace (aliasing ssortingct), C est en réalité fortement typé – le système de types est tout simplement peu sain (c’est-à-dire qu’il ne vous protège pas de la violation de ses invariants) …