Digite teoricamente falando, voidé o que é chamado em outros idiomas unitou top. Seu equivalente lógico é True . Qualquer valor pode ser legitimamente convertido para void(todo tipo é um subtipo de void). Pense nisso como um conjunto de "universo"; não há operações em comum a todos os valores no mundo, para que não haja operações válidas em um valor do tipo void. Dito de outra maneira, dizer que algo pertence ao conjunto do universo não fornece nenhuma informação - você já sabe disso. Portanto, o seguinte é válido:
(void)5;
(void)foo(17); // whatever foo(17) does
Mas a tarefa abaixo não é:
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]], Por outro lado, é chamado às vezes empty, Nothing, Bottomou Bote é o equivalente lógico de Falso . Ele não possui valores, e uma expressão desse tipo pode ser convertida para (ou seja, é subtipo de) qualquer tipo. Este é o conjunto vazio. Observe que se alguém lhe disser "o valor da expressão foo () pertence ao conjunto vazio" é altamente informativo - informa que essa expressão nunca concluirá sua execução normal; irá abortar, jogar ou travar. É exatamente o oposto de void.
Portanto, o seguinte não faz sentido (pseudo-C ++, pois noreturnnão é do tipo C ++ de primeira classe)
void foo();
(noreturn)5; // obviously a lie; the expression 5 does "return"
(noreturn)foo(); // foo() returns void, and therefore returns
Mas a atribuição abaixo é perfeitamente legítima, pois throwé entendida pelo compilador como não retornando:
void f(int y) {
int x = y!=0 ? 100/y : throw exception();
cout << x << endl;
}
Em um mundo perfeito, você pode usar noreturncomo valor de retorno para a função raise()acima:
noreturn raise() { throw exception(); }
...
int x = y!=0 ? 100/y : raise();
Infelizmente, o C ++ não permite isso, provavelmente por razões práticas. Em vez disso, oferece a capacidade de usar [[ noreturn ]]atributos que ajudam a orientar otimizações e avisos do compilador.