Pourquoi le type void de C n'est-il pas analogue au type vide / bas?

28

Wikipédia ainsi que d'autres sources que j'ai trouvées listent le voidtype C comme type d'unité par opposition à un type vide. Je trouve cela déroutant car il me semble que cela voidcorrespond mieux à la définition d'un type vide / bas.

  • Autant voidque je sache , aucune valeur n'habite .
  • Une fonction avec un type de retour void spécifie que la fonction ne retourne rien et ne peut donc effectuer que des effets secondaires.
  • Un pointeur de type void*est un sous-type de tous les autres types de pointeurs. De plus, les conversions vers et depuis void*en C sont implicites.

Je ne sais pas si le dernier point a un quelconque mérite comme argument pour voidêtre un type vide, comme void*c'est plus ou moins un cas spécial avec peu de relation avec void.

D'un autre côté, voidlui-même n'est pas un sous-type de tous les autres types, ce qui, pour autant que je sache, est une exigence pour qu'un type soit un type inférieur.

Meta
la source
10
Par "ne retourne rien", vous voulez dire "ne retourne rien d'intéressant", alors qu'une fonction avec une sortie vide ne retourne pas du tout (c'est-à-dire plante ou boucle indéfiniment).
Turion
2
En tant que type de retour, void est un type d'unité.
user253751

Réponses:

38

En C, voidest utilisé pour plusieurs choses sans rapport. En fonction de son utilisation, sa signification peut être un type d'unité, un type vide ou autre chose.

voidvoid*void020=1

Ce n'est pas un type vide: une fonction qui retourne un type vide ne peut pas retourner une valeur, car il n'y a pas de valeur de ce type. Une fonction dont le type de retour est vide ne peut que boucler indéfiniment, ou abandonner le programme, ou lever une exception ( longjmp) (ou autrement prendre des dispositions pour ne pas revenir, par exemple en transférant le contrôle vers un autre thread ou processus en utilisant des fonctionnalités au-delà du standard C). Pour éviter toute confusion, il est classique en C d'utiliser voidà la place d'un type vide (C n'a pas de type vide).

void0voidvoidreturnvoidvoid

C n'a pas de type bas dans le sens d'autoriser tout type possible. Même les types incomplets spécifient la nature générale de ses valeurs, par exemple des pointeurs ou des structures ou des unions ou des fonctions. Mais void*est un pointeur vers n'importe quel type de non-fonction: c'est le moindre élément de l'algèbre des types de pointeurs d'objets, c'est-à-dire que c'est le type de pointeur d'objet inférieur. Contrairement au cas général T*où se Ttrouve un type non vide, ce void*n'est pas le type de pointeurs vers une valeur de type void, mais le type de pointeurs vers une valeur de type non spécifié.

Gilles 'SO- arrête d'être méchant'
la source
On peut retourner vide en C ++ et C89. stackoverflow.com/questions/35987493/…
BartekChom
2
Le quatrième paragraphe est formellement faux. En C, la quantité de stockage pour voidn'est pas définie, pas zéro. Ce n'est pas la raison pour laquelle les objets de type voidsont interdits. La raison formelle est qu'il voids'agit d'un type incomplet et que les objets ne peuvent pas avoir un type incomplet.
MSalters
4
@MSalters Non, ce que j'ai écrit est formellement correct. «Parce que» fait référence à la motivation pour la conception du langage, et non aux inférences logiques à l'intérieur de la spécification du langage. Le voidtype nécessite 0 bits de stockage. C'est la raison pour laquelle les concepteurs de C ont décidé de faire voidun type incomplet, au lieu de le définir en prenant 0 octets de stockage (ce qui aurait beaucoup d'impact sur la conception du langage) ou 1 octet de stockage (ce qui gaspillerait de l'espace) .
Gilles 'SO- arrête d'être méchant'
1
@ Gilles: Désolé, mais cela n'a pas de sens non plus. Si autorisé, l'espace utilisé serait de 1 octet par objet de type void , et vous n'avez évidemment pas besoin de beaucoup d'objets de voidtype. Sans oublier que ces objets pourraient alias tous les autres objets, donc l'utilisation réelle serait de toute façon nulle.
MSalters
4
@CodesInChaos: Eh bien, C ++ autorise en fait des structures vides, c'est-à-dire struct E { };. Lorsqu'elle est utilisée comme classe de base, elle peut être de taille nulle. (Il n'y a vraiment rien de tel que C / C ++, les deux langages font leurs propres choix et ils peuvent différer dans ces domaines. C n'a évidemment pas de classes de base vides, car il n'a pas OO en premier lieu)
MSalters
11

Le nom «type vide» prête peut-être à confusion. Cela signifie que, comme vous le dites vous-même, le type ne contient aucune valeur . Le «vide» ne fait référence à aucune valeur individuelle du type, il fait référence au type dans son ensemble, considéré comme un ~ ensemble de valeurs possibles. Donc, cela ne dit pas quelque chose comme «une fonction renvoyant voidne renvoie aucune information», mais «il n'existe aucune valeur de type ».

Cela signifie qu'une fonction dont le type de résultat est ne peut jamais se terminer. S'il s'est terminé, il devrait renvoyer une valeur de , mais bon, une telle valeur n'existe pas.

Cela signifie également qu'il n'est même pas possible de discuter de la quantité d'informations qu'une valeur de type vide contiendrait, car il n'y a pas une telle valeur. (Ou si vous voulez, une déclaration absurde comme «toute valeur de type vide contient exactement 35093658 bits d'informations» est tout à fait vraie.) Il est quelque peu utile (mais pas vraiment correct) de penser que les valeurs contiennent une quantité infinie d'informations.

Alors qu'une fonction C avec «type de retour» peutvoid clairement retourner, mais ne vous donne aucune information dans sa valeur de retour. Eh bien, c'est précisément ce qui caractérise un type d'unité: ses valeurs ne contiennent aucune information, car il n'y a qu'une seule de ces valeurs (vous pouvez donc toujours dire quelle sera la valeur de retour, même sans prendre la peine d'appeler la fonction).

Pour citer Conor McBride (translittéré en C):

voidsignifie "ennuyeux". Cela signifie le type ennuyeux qui contient une chose, également ennuyeux. Il n'y a rien d'intéressant à gagner en comparant un élément du type ennuyeux à un autre, car il n'y a rien à apprendre sur un élément du type ennuyeux en lui accordant toute votre attention.

Il est très différent du type vide [...]. Le type vide est très excitant, car si quelqu'un vous donne jamais une valeur qui lui appartient, vous savez que vous êtes déjà mort et au paradis et que tout ce que vous voulez vous appartient.

à gauche
la source
Intéressant; si la définition de ⊥ est la fonction dont le type de retour est ⊥ ne peut jamais se terminer, alors C a un tel type. Nous appelons cela un vide volatil.
Joshua
Intéressant, je ne le savais pas. Cependant, je ne semble pas être conforme aux normes .
partir du