2013-06-20 6 views
8

Il seguente programma emette sempre "Errore: doppio 10.2".gestione delle eccezioni in C++: lancio di un doppio quando si utilizza "throw (int)"

Non capisco perché. Secondo me, se fun1() consente di lanciare solo int, il programma deve arrestare (1) o cambiare il doppio in un int e poi lanciare. Ciò significa che l'output dovrebbe essere "Errore: int 10". Tuttavia, questo non è il caso. Qualcuno può spiegare ??

void fun1() throw (int) 
{ 
    cout<<"3"; 
    throw 10.2; 
    cout<<"4"; 
} 

int main() 
{ 
    try { fun1(); } 
    catch(int i) { cout<<"Error:int" <<i <<endl;} 
    catch(double i) { cout << "Error:double" << i << endl; } 
    cout << endl; 
    return 0; 
} 
+10

Non utilizzare la dichiarazione di funzione "throw", è una funzionalità schifosa ed è stata deprecata. – piokuc

+0

Stai usando MSVC? Non ha mai veramente supportato le specifiche delle eccezioni. – Fanael

+4

Questo dovrebbe essere 'int main()'. –

risposta

9

Il compilatore non è conforme allo standard. Secondo lo standard, il programma dovrebbe terminare chiamando std::unexpected dopo aver lasciato l'escape doublefun1.
Detto questo: non utilizzare le specifiche delle eccezioni. Sono deprecati e inutili.

+3

E qui è una lettura interessante sull'argomento del perché: http://www.gotw.ca/publications/mill22 .htm –

3

MSVC tratta throw(int) nel senso semplicemente "può buttare via nulla", cioè equivalente a throw(...), vedere Exception Specifications (MSDN)

Questo non è conforme allo standard C++ 03, ma in realtà è più utile del C++ 03 comportamento ed è più vicino allo spirito dello standard C++ 11.

In C++ 11 throw(X) è obsoleto, la nuova forma di specifica eccezione è noexcept e può essere noexcept(true) o noexcept(false), equivalenti a throw() e throw(...), che è tutto ciò che MSVC supporta.

Se si desidera utilizzare le specifiche eccezioni vecchio stile, basta usare throw() per dire "non buttare" e nulla o throw(...) da dire "potrebbe gettare", e non utilizzare throw(X). Funzionerà in modo coerente in C++ 03 e C++ 11 e su tutti i compilatori.

+1

MSVC non supporta correttamente 'throw()' o: ["Tuttavia, se un'eccezione viene respinta da una funzione contrassegnata da throw(), il compilatore di Visual C++ non chiamerà inaspettato ..."] (http://msdn.microsoft.com/en-us/library/wfa0edys.aspx). Non è possibile utilizzare alcun tipo di specifica 'throw' tra MSVC e un compilatore conforme allo standard. – Casey

+0

Ah sì, l'ho dimenticato ... quindi non corrisponde alla semantica di C++ 11, che dichiara che 'std :: terminate()' viene chiamato se una funzione 'noexcept (true)' (o 'throw() ') lancia –