2013-06-20 10 views
8

Następujący program zawsze wyświetla "Błąd: podwójne 10.2".Obsługa wyjątków w C++: Rzucanie podwójnym przy użyciu "throw (int)"

Nie rozumiem dlaczego. Według mnie, jeśli fun1() pozwala tylko na wyrzucenie int, program powinien albo (1) rozbić (2) lub zmienić double na int, a następnie wyrzucić. Oznacza to, że wyjście powinno być "Błąd: int 10". Tak jednak nie jest. Czy ktoś może wyjaśnić?

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

Nie używaj deklaracji funkcji "throw", jest to funkcja crap i została wycofana. – piokuc

+0

Czy używasz MSVC? Nigdy nie obsługiwał specyfikacji wyjątków. – Fanael

+4

To powinno być 'int main()'. –

Odpowiedz

9

Twój kompilator nie jest zgodny ze standardem. Zgodnie z normą program powinien kończyć się dzwonieniem pod numer std::unexpected po wyjściu z double wyjątku z numeru fun1.
To powiedziawszy - nie używaj specyfikacji wyjątków. Są one przestarzałe i bezużyteczne.

+3

A oto ciekawa lektura na temat: http://www.gotw.ca/publications/mill22 .htm –

3

MSVC traktuje throw(int) w ten sposób po prostu „może rzucić wszystko”, czyli odpowiednik throw(...) patrz Exception Specifications (MSDN)

nie są zgodne z standardem C++ 03, ale jest rzeczywiście bardziej użyteczne niż C++ 03 zachowanie i jest bliżej ducha standardu C++ 11.

C++ 11 throw(X) jest nieaktualny, nowa postać wyjątek specyfikacji jest noexcept i może być noexcept(true) lub noexcept(false) ekwiwalent throw() i throw(...), co wszystko MSVC podpór.

Jeśli chcesz korzystać w starym stylu wyjątek specyfikacji, wystarczy użyć throw() powiedzieć „nie rzucać” i albo nic lub throw(...) do powiedzenia „może rzucać”, a nie używać throw(X). To będzie działać konsekwentnie w C++ 03 i C++ 11 oraz we wszystkich kompilatorach.

+1

MSVC nie obsługuje poprawnie funkcji 'throw()': ["Jednakże, jeśli wyjątek jest wyrzucony z funkcji oznaczonej throw(), kompilator Visual C++ nie wywoła nieoczekiwanego ..."] (http://msdn.microsoft.com/en-us/library/wfa0edys.aspx). Nie można używać żadnego rodzaju specyfikacji rzutowania między MSVC a kompilatorem zgodnym ze standardami. – Casey

+0

Ach tak, zapomniałem o tym ... więc nie pasuje do semantyki C++ 11, która stwierdza, że ​​'std :: terminate()' jest wywoływane, jeśli funkcja 'noexcept (true)' (lub 'throw '() ') wyrzuca –