Peguei isso em uma de minhas breves incursões ao reddit:
http://www.smallshire.org.uk/sufficientlysmall/2009/07/31/in-c-throw-is-an-expression/
Basicamente, o autor aponta que em C ++:
throw "error"
é uma expressão. Na verdade, isso é explicado com bastante clareza no padrão C ++, tanto no texto principal quanto na gramática. Porém, o que não está claro (pelo menos para mim) é qual é o tipo da expressão? Achei " void
", mas alguns experimentos com g ++ 4.4.0 e Comeau produziram este código:
void f() {
}
struct S {};
int main() {
int x = 1;
const char * p1 = x == 1 ? "foo" : throw S(); // 1
const char * p2 = x == 1 ? "foo" : f(); // 2
}
Os compiladores não tiveram problemas com // 1, mas vomitaram em // 2 porque os tipos no operador condicional são diferentes. Portanto, o tipo de throw
expressão não parece ser vazio.
Então o que é?
Se você responder, faça backup de suas declarações com citações do Padrão.
Isso acabou não sendo tanto sobre o tipo de expressão de lançamento, mas como o operador condicional lida com expressões de lançamento - algo que eu certamente não sabia antes de hoje. Obrigado a todos que responderam, mas particularmente a David Thornley.
Respostas:
De acordo com o padrão, 5.16 parágrafo 2 primeiro ponto, "O segundo ou o terceiro operando (mas não ambos) é uma expressão de lançamento (15.1); o resultado é do tipo do outro e é um rvalue." Portanto, o operador condicional não se importa com o tipo de expressão de lançamento, mas apenas usará o outro tipo.
Na verdade, 15.1, parágrafo 1 diz explicitamente "Uma expressão de lançamento é do tipo vazio."
fonte
ISO14882 Seção 15
fonte
void
De [expr.cond.2] (operador condicional
?:
):Então, com
//1
você estava no primeiro caso, com//2
, você estava violando "um dos seguintes deve manter", já que nenhum deles faz, nesse caso.fonte
Você pode ter um tipo de impressora que expõe para você :
Basicamente, a falta de implementação de
PrintType
fará com que o relatório de erro de compilação diga:então podemos realmente verificar se as
throw
expressões são do tipovoid
(e sim, as citações padrão mencionadas em outras respostas verificam que este não é um resultado específico da implementação - embora o gcc tenha dificuldade em imprimir informações valiosas)fonte