2

Im trying to catch an exception thrown when an error ocurred reading a file in a class method from main. The simplified code is this:

#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;
    }

}

I compile this code with:

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

If file.txt exists nothing happens, but when it doesn't, the program terminates with the following error:

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

But I expected the code to catch the exception and show the error message. Why is it not catching the exception?

Msegade
  • 476
  • 7
  • 17

1 Answers1

3

You can get it to work in GCC by adding -D_GLIBCXX_USE_CXX11_ABI=0 to the command line. Here is a working example with GCC.

From the comments (especially LogicStuff's tests) below and my own test it seems that in clang and MSVC it does not produce this error.

Thanks to LogicStuff's comment above we now know that this is a GCC bug. Because in GCC C++03 ios::failure doesn't derive from runtime_error and so was not caught.

Another option could be to change to:

try
{
    A MyClass(filename);
}
catch (std::ifstream::failure e)
{
    std::cerr << "Error reading file\n";
}
catch (...)
{
    std::cerr << "Some other error\n";
}
wally
  • 10,717
  • 5
  • 39
  • 72
  • Does not crash [here](http://coliru.stacked-crooked.com/a/c52d4b1cce7814b8). And `std::ifstream::failure` is supposed to be same as `std::ios_base::failure`. It's inherited. – LogicStuff Feb 29 '16 at 18:20
  • 3
    `std::ios_base::failure` and `std::ifstream::failure` are the *same* type. – Christian Hackl Feb 29 '16 at 18:21
  • 3
    Since `exceptions` in `ifstream` is inherited from `std::basic_ios` It should be the same type – NathanOliver Feb 29 '16 at 18:21
  • 1
    Check [this](http://coliru.stacked-crooked.com/a/d0518c8c69a83979) out, it crashes on GCC, but not with Clang (above). – LogicStuff Feb 29 '16 at 18:28