2
votes

I am reading data from file with an fstream object, while using exception handling. Because of how the logic is implemented, the code will execute a tellg() on the fstream after a fstream::failure exception is thrown when the end-of-file is hit. This execution flow is not necessarily intentional, but it hasn't caused any problems when running on Windows (MSVS 2010) or CentOS6. But, when running on CentOS7, I get a core dump. If I add a call to clear() the fstream prior to the tellg(), all is good.

There error that is thrown is:

terminate called after throwing an instance of 'std::ios_base::failure' what(): basic_ios::clear

Can someone provide insight as to whether this change in behavior is expected, or not?

The applicable versions of gcc and libstdc++ are:

For CentOS6:

  • gcc version 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)
  • /usr/lib64/libstdc++.so.6.0.13

For CentOS7:

  • gcc version 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC)
  • /usr/lib64/libstdc++.so.6.0.19

A code sample that exercises the issue follows:

#include <fstream>
#include <iostream>

using namespace std;

int main()
{
   fstream in;
   in.exceptions(ifstream::failbit);

   cout << "Before open" << endl;
   in.open("in.txt", ios::in);
   cout << "After open" << endl;

   try
   {
      string s;
      while ( 1 )
      {
         getline(in, s);
         cout << s << endl;
      }
   }
   catch(fstream::failure e)
   {
      cout << "EOF Exception." << endl;
   }
   catch(...)
   {
      cout << "Unhandled Exception." << endl;
   }

   // --- uncomment this to make it work ---  in.clear();
   in.tellg();

   return 0;
}

Thanks for the help!

1

1 Answers

1
votes

As shown in PR 26211 GCC 4.6.0 implements the resolution of DR 419, so the new behaviour is intentional.

There was a defect in the standard, which was fixed, and so GCC's library was changed to match the new specification in the standard.