2016-02-29 3 views
1

Im пытается поймать исключение, возникшее при ошибке при чтении файла в методе класса из основного. Упрощенный код заключается в следующем:Исключение исключения ifstream в основном

#include <iostream> 
#include <fstream> 
#include <string> 

class A 
{ 
public: 
    A(const std::string filename) 
    { 
     std::ifstream file; 
     file.exceptions(std::ifstream::failbit | std::ifstream::badbit); 
     file.open(filename); 
    } 

}; 

int main() 
{ 
    std::string filename("file.txt"); 
    try 
    { 
     A MyClass(filename); 
    } 
    catch (std::ifstream::failure e) 
    { 
     std::cerr << "Error reading file" << std::endl; 
    } 

} 

Я скомпилировать этот код:

$ g++ -std=c++11 main.cpp 

Если file.txt существует ничего не происходит, но когда это не так, то программа завершается со следующей ошибкой:

terminate called after throwing an instance of 'std::ios_base::failure' 
    what(): basic_ios::clear 
zsh: abort (core dumped) ./a.out 

Но я ожидал, что код поймает исключение и покажет сообщение об ошибке. Почему он не ловит исключения?

+0

какую версию компилятора? Здесь отлично работает. –

+0

@Christian Hackl g ++ vresion 5.3.0 – Msegade

+3

@Msegade Это ошибка [GCC] (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145). – LogicStuff

ответ

2

Вы можете заставить его работать в GCC, добавив -D_GLIBCXX_USE_CXX11_ABI=0 в командную строку. Here - рабочий пример с GCC.

Из комментариев (особенно тестов LogicStuff) ниже и моего собственного теста кажется, что в clang и MSVC он не производит эту ошибку.

Благодаря замечанию LogicStuff выше, мы теперь знаем, что это GCC bug. Потому что в GCC C++ 03 ios :: failure не получается из runtime_error и поэтому не был пойман.

Другим вариантом может быть, чтобы изменить:

try 
{ 
    A MyClass(filename); 
} 
catch (std::ifstream::failure e) 
{ 
    std::cerr << "Error reading file\n"; 
} 
catch (...) 
{ 
    std::cerr << "Some other error\n"; 
} 
+0

Не сбой [здесь] (http://coliru.stacked-crooked.com/a/c52d4b1cce7814b8). И 'std :: ifstream :: failure' должен быть таким же, как' std :: ios_base :: failure'. Это унаследовано. – LogicStuff

+2

'std :: ios_base :: failure' и' std :: ifstream :: failure' являются * одинаковыми * типами. –

+2

Поскольку 'exceptions' в' ifstream' наследуется от 'std :: basic_ios' Он должен быть того же типа – NathanOliver

Смежные вопросы