Type théoriquement parlant, void
c'est ce qu'on appelle dans d'autres langues unit
ou top
. Son équivalent logique est True . Toute valeur peut être convertie légitimement en void
(chaque type est un sous-type de void
). Pensez-y comme un ensemble «univers»; il n'y a pas d'opérations communes à toutes les valeurs du monde, il n'y a donc pas d'opérations valides sur une valeur de type void
. En d'autres termes, vous dire que quelque chose appartient à l'univers ne vous donne aucune information - vous le savez déjà. Donc, ce qui suit est sain:
(void)5;
(void)foo(17); // whatever foo(17) does
Mais la mission ci-dessous n'est pas:
void raise();
void f(int y) {
int x = y!=0 ? 100/y : raise(); // raise() returns void, so what should x be?
cout << x << endl;
}
[[noreturn]]
, D'autre part, que l' on appelle parfois empty
, Nothing
, Bottom
ou Bot
et est l'équivalent logique de faux . Il n'a aucune valeur du tout et une expression de ce type peut être transtypée en (c'est-à-dire est un sous-type de) n'importe quel type. Ceci est l'ensemble vide. Notez que si quelqu'un vous dit que «la valeur de l'expression foo () appartient à l'ensemble vide», c'est très informatif - cela vous dit que cette expression ne terminera jamais son exécution normale; il va abandonner, lancer ou se bloquer. C'est exactement le contraire de void
.
Donc, ce qui suit n'a pas de sens (pseudo-C ++, car ce noreturn
n'est pas un type C ++ de première classe)
void foo();
(noreturn)5; // obviously a lie; the expression 5 does "return"
(noreturn)foo(); // foo() returns void, and therefore returns
Mais l'affectation ci-dessous est parfaitement légitime, car il throw
est entendu par le compilateur de ne pas retourner:
void f(int y) {
int x = y!=0 ? 100/y : throw exception();
cout << x << endl;
}
Dans un monde parfait, vous pouvez utiliser noreturn
comme valeur de retour pour la fonction raise()
ci-dessus:
noreturn raise() { throw exception(); }
...
int x = y!=0 ? 100/y : raise();
Malheureusement, C ++ ne le permet pas, probablement pour des raisons pratiques. Au lieu de cela, il vous permet d'utiliser un [[ noreturn ]]
attribut qui aide à guider les optimisations et les avertissements du compilateur.