2016-10-25 10 views
5

Używałem tutaj MWE: http://www.cplusplus.com/reference/ios/ios/exceptions/ Na moim komputerze nie przechwytuje wyjątku. Oto mój kodWyjątek nie został przechwycony przez otwarcie nieistniejącego pliku przy użyciu C++

#include <iostream> 
#include <fstream> 

int main() 
{ 
    std::ifstream file; 
    file.exceptions(std::ifstream::failbit | std::ifstream::badbit); 
    try 
    { 
     file.open("IDoNotExist.txt"); 
    } 
    catch(const std::ifstream::failure& e) 
    { 
     std::cout << "Bad luck!" << std::endl; 
    } 
} 

Korzystanie gcc 6.2.1 na Arch-Linux uzyskać:

terminate nazywany po wrzuceniu instancję 'std :: ios_base :: awarii'

co(): basic_ios :: wyczyść

Jednak na zamieszczonym powyżej łączu wspomina się, że kod powinien również wychwycić wyjątek związany z otwieraniem pliku. Co poszło nie tak?

+2

To wygląda na zły przykład. Po pierwsze, wyjątek powinien być przechwytywany przez odniesienie do stałej, tak jak robisz, ale tak nie jest. – NathanOliver

+0

Z g ++ 6.2.0 na (inna dystrybucja) Linuksa, ten program wypisze "Pech!". Wiem też, że ten program może złapać wyjątek 'failure' i wydrukować" Pech "! (zakładając, że "IDoNotExist.txt" naprawdę nie istnieje). Dlatego Twój kompilator C++ i/lub środowisko wykonawcze działają nieprawidłowo. Najbardziej prawdopodobną przyczyną jest to, że są źle zainstalowane. Spróbuj odinstalować i ponownie zainstalować każdy pakiet z 'g ++' lub 'C++' w nazwie. – zwol

+0

Chociaż cplusplus.com ma swoje pozytywne strony, ma również swoje negatywne strony (są podzielone przeciwności dotyczące strony, szukaj go, jeśli chcesz wiedzieć więcej). Wolę zamiast tego [tę stronę referencyjną] (http://en.cppreference.com/w/cpp) i wydaje się być bardziej aktualna i dokładna. Na przykład jest to przykład w [wyjątkach strumienia I/O] (http://en.cppreference.com/w/cpp/io/basic_ios/exceptions) używa właściwej klasy do przechwytywania. –

Odpowiedz

1

Wygląda jak known bug in libstdc++.

Problem polega na tym, że wraz ze zmianą w CII ABI 11, wiele klas zostało zduplikowanych w libstdc++6.so, jedna wersja ze starym ABI, a druga z nowym.

Klasy wyjątków nie zostały zduplikowane, więc ten problem nie występował w tym czasie. Ale później, w nowszej wersji języka, zdecydowano, że std::ios_base::failure powinno pochodzić od std::system_error zamiast std::exception ... ale system_error jest klasą tylko C++ 11, więc musi użyć nowej flagi ABI lub będzie narzekać. Teraz masz dwie różne klasy std::ios_base::failure i bałagan w Twoich rękach!

Łatwym rozwiązaniem jest skompilowanie programu za pomocą -D_GLIBCXX_USE_CXX11_ABI=0 i rezygnacja ze starego ABI do czasu usunięcia błędu. Lub napisz: catch (std::exception &e).

Powiązane problemy