Inconvénients de l’utilisation de pointeurs void * en C

L’utilisation de void * en C présente de nombreux inconvénients (mémoire, type, efficacité, etc.). Malgré eux, nous les utilisons beaucoup pour la flexibilité qu’ils offrent.

Enumérer les inconvénients / inconvénients en utilisant void * (et la solution recommandée en C – si possible).

EDIT: veuillez suivre le lien suivant: http://attractivechaos.wordpress.com/2008/10/02/using-void-in-generic-c-programming-may-be-inefficient/

Il n’y a pas de problèmes d’efficacité avec les pointeurs vides. Les seules limitations concernant les pointeurs vides sont les suivantes:

  • vous ne pouvez pas déréférencer le pointeur vide pour des raisons évidentes
  • sizeof(void) est illégal
  • vous ne pouvez pas effectuer d’arithmétique de pointeur sur des pointeurs vides

Cependant, GCC suppose que sizeof(void) est sizeof(void) 1 et autorise l’arithmétique de pointeur sur les pointeurs de vide – voir ici

Je ne suis pas d’accord avec la prémisse de la question. Nous utilisons void * en C parce que c’est le seul moyen d’obtenir un polymorphism. Exemple: fonctions de bibliothèque qsort et bsearch. Il n’ya qu’un inconvénient, à savoir que le polymorphism basé sur void * n’est pas sûr: une fois que vous avez jeté un pointeur sur void *, rien ne vous empêche de jeter ce vide * par erreur sur le mauvais type de pointeur. Mes étudiants font souvent cette erreur.

Il peut y avoir un coût d’efficacité car il est parfois nécessaire d’allouer de l’espace de tas afin d’utiliser une structure de données polymorphe.

Quiconque souhaite voir les avantages et les inconvénients de l’utilisation de structures de données polymorphes avec void * devrait obtenir un exemplaire du livre C de Dave Hanson, Interfaces and Implementations.

Euh … je ne suis pas sûr qu’il y en a autant. Bien sûr, vous ne devez jamais utiliser void* lorsque vous n’êtes pas obligé de le faire. Si vous pouvez utiliser un type bien défini, faites-le.

D’après mon expérience, void* est préférable pour les pointeurs “anonymes” (quel choc!), Comme dans la valeur de retour de malloc() et lorsqu’il s’agit uniquement de tampons de bits opaques. Souvent, vous souhaitez adresser ces tampons au niveau des octets, par exemple, puis vous utilisez un caractère unsigned char * , bien sûr.

Utiliser au hasard void* partout où vous auriez besoin d’un pointeur ne serait que du code cassé, malodorant, et à éviter bien sûr.

La publication liée compare les opérations avec des pointeurs vides aux opérations avec des modèles C ++ et conclut que les modèles sont plus efficaces. Ce n’est pas une surprise et le code C ++ que j’ai vu utilise des pointeurs nuls rarement ou jamais. Il n’offre généralement aucun avantage par rapport aux autres installations C ++ et peut constituer un trou béant dans le système de types.

Cependant, C n’a pas de modèles de style C ++, et les pointeurs vides sont nécessaires pour implémenter des fonctionnalités qui doivent être indépendantes du type de données.

Par conséquent, lorsque vous écrivez en C et que vous avez besoin de généricité, les pointeurs vides sont le moyen le plus efficace pour l’obtenir (car ils sont le seul moyen). Lorsque vous écrivez en C ++, il existe de meilleures façons de faire presque tout ce que les pointeurs vides peuvent accomplir. Ne les utilisez pas.

Votre lien donné est partiellement vrai. Surtout lorsque vous ne traitez pas d’objects (structs), ou en général avec des types qui ne sont pas déjà alloués. Utiliser des types natifs tels que ints, doubles, etc. et les pointeurs de vide (par exemple pour un conteneur) est presque toujours une affaire épineuse, car vous avez le choix de transtyper l’int (pour un double cela ne fonctionne pas) en pointeur ou vous devez allouer de la mémoire supplémentaire pour le type de données.

Le premier choix est mauvais car il n’est pas portable, les 0 ne sont peut-être pas autorisés en tant que valeur et on se sent tout simplement mal. Le second choix gaspille de la mémoire et constitue en fait un ralentissement (massif) en raison des allocations supplémentaires.

Mais dans la plupart des cas, vous ne traitez pas avec des types natifs, mais avec des objects, mieux avec des pointeurs sur des objects, qui sont déjà alloués, du moins je le fais. Je n’ai jamais eu besoin d’une table de hachage ou d’une carte pour les entiers ou les doubles. Et avoir différentes implémentations de conteneur uniquement pour la sécurité des types de pointeurs me semble inacceptable, car chaque implémentation augmentera votre taille binary. Donc, si vous n’avez besoin que d’un conteneur pour stocker vos pointeurs, il n’ya pas de ralentissement ni de perte de mémoire lors de l’utilisation de pointeurs vides.

Mais notez bien que tout concernait l’implémentation de conteneurs, comme l’article de blog que vous avez mentionné. En général, il y a beaucoup de choses que vous ne pouvez pas accomplir sans utiliser des pointeurs de vide.

Je ne sais pas, j’ai trouvé les pointeurs vides assez efficaces pour accéder à différents niveaux d’abstraction (ABC). Comme moyen de naviguer dans des classes nestedes à différents niveaux d’abstraction. C’est tellement simple, c’est génial. Comme pour la formule pour e ou le nombre d’or, il devrait y avoir un occulte vénérant le vide * c’est génial 🙂