Digitare teoricamente parlando, void
è ciò che viene chiamato in altre lingue unit
o top
. Il suo equivalente logico è True . È possibile eseguire il cast legittimo di qualsiasi valore void
(ogni tipo è un sottotipo di void
). Pensalo come un set di "universo"; non ci sono operazioni in comune con tutti i valori nel mondo, quindi non ci sono operazioni valide su un valore di tipo void
. Detto in altro modo, dirti che qualcosa appartiene all'insieme dell'universo non ti dà alcuna informazione - lo sai già. Quindi è il seguente suono:
(void)5;
(void)foo(17); // whatever foo(17) does
Ma il seguente incarico non è:
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'altra parte, è chiamato a volte empty
, Nothing
, Bottom
o Bot
ed è l'equivalente logico di False . Non ha alcun valore e un'espressione di questo tipo può essere lanciata su (cioè è il sottotipo di) qualsiasi tipo. Questo è l'insieme vuoto. Nota che se qualcuno ti dice "il valore dell'espressione foo () appartiene all'insieme vuoto" è altamente informativo - ti dice che questa espressione non completerà mai la sua normale esecuzione; si interromperà, lancerà o si bloccherà. È l'esatto contrario di void
.
Quindi non ha senso quanto segue (pseudo-C ++, poiché noreturn
non è un tipo C ++ di prima classe)
void foo();
(noreturn)5; // obviously a lie; the expression 5 does "return"
(noreturn)foo(); // foo() returns void, and therefore returns
Ma il seguente incarico è perfettamente legittimo, poiché throw
il compilatore è inteso a non restituire:
void f(int y) {
int x = y!=0 ? 100/y : throw exception();
cout << x << endl;
}
In un mondo perfetto, potresti usare noreturn
come valore di ritorno per la funzione raise()
sopra:
noreturn raise() { throw exception(); }
...
int x = y!=0 ? 100/y : raise();
Purtroppo C ++ non lo consente, probabilmente per motivi pratici. Ti dà invece la possibilità di utilizzare l' [[ noreturn ]]
attributo che aiuta a guidare le ottimizzazioni e gli avvisi del compilatore.