/* Below is a test program that I wrote to try and discern how exceptions work when persistent streams encounter errors.
The bottom line is that you can pretty much ignore any sort of exception support in the persistent streams package. From what I've been able to find out, it will never throw any exceptions from the various read and write methods. So you are left to try and use the standard C++ library iostreams for exceptions, except, they appear to not implement them in compliance with the ISO specifications either (see http://gcc.gnu.org/onlinedocs/libstdc++/ext/lwg-defects.html#211). Although, this is for reading strings while the persistent stream is reading binary, so this may not apply. What I did find out is that you can make use of exceptions, but you have to check the state of the file stream, figure out which issue is the problem, and throw a PersistException in your low level code. Then you high lever code can actually use the appropriate catch clauses to handle the throw exceptions. Not pretty, but I guess it'll do for now. I'm just hoping that this will end up helping someone out there, as I've asked about this a number of times and really didn't receive very many responses. The test program below is what I used to selectively comment out specific statements and parts, run, and record the results. It should be nothing more than a copy/paste operation into your favorite editor to get it being useful for you. Software versions: gcc --version: gcc (GCC) 3.3.6 (Gentoo 3.3.6, ssp-3.3.6-1.0, pie-8.7.8) libstdc++: as released as part of gcc above commoncpp2: 1.3.1 */ #include <errno.h> #include <fstream> #include <cc++/persist.h> using namespace std; using namespace ost; int main( int argc, char** argv ) { set_terminate( __gnu_cxx::__verbose_terminate_handler ); const char* cFileName = "exception.obst"; const int cIterm = 10; // write out a stream fstream outputArchive( cFileName, ios::out | ios::binary ); Engine outputEngine( outputArchive, Engine::modeWrite ); for( int i = 0; i < cIterm; i++ ) { outputEngine << i; } outputArchive.close(); // Read in the stream expecting an exception (we are reading N+1 items) try { // Automatic scope instance DTOR closes file, exception or not. fstream inputArchive( cFileName, ios::in | ios::binary ); // If we use this, it'll cause a core dump and no exception handling // This according to: http://www.cplusplus.com/ref/iostream/ios/exceptions.html //inputArchive.exceptions( fstream::eofbit | fstream::failbit | fstream::badbit ); // which results in core dump after the extraction to int // However, according to: // http://gcc.gnu.org/onlinedocs/libstdc++/ext/lwg-defects.html#211 // at one time, extracting at end of file didn't set the failbit, but // should now. So how come we get a core dump? // Interestingly, on: http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/CHECKLIST // it shows that ios_base::exceptions( arg ) status as missing(!?) // If we use: inputArchive.exceptions( fstream::badbit ); // exception caught, but no info (unless we enable it by checking inputArchive flags //inputArchive.exceptions( fstream::eofbit ); // results in core dump after the extraction to int //inputArchive.exceptions( fstream::failbit ); // results in core dump after the extraction to int //inputArchive.exceptions( fstream::badbit | fstream::eofbit ); // results in core dump after the extraction to int //inputArchive.exceptions( fstream::badbit | fstream::failbit ); // results in core dump after the extraction to int Engine inputEngine( inputArchive, Engine::modeRead ); for( int i = 0; i < cIterm + 1; i++ ) { string err; int data; inputEngine >> data; err = strerror( errno ); if( !inputArchive.good() ) { #if 1 // If we don't use this, we get no deails. if( inputArchive.eof() ) err = "eof hit"; if( inputArchive.bad() ) err = "bad stream state"; if( inputArchive.fail() ) err = "extraction failed"; #endif // if we don't do this, we get no exception thrown, and read an item 10 // so we can throw either of these. //throw ios::failure( err.c_str() ); throw PersistException( err.c_str() ); } cout << "read item: " << i << endl; } } // catches, from most specific to most general. catch( Engine::Exception& e ) // persist Engine exception { cout << "Engine::Exception caught! " << e.getString() << endl; } catch( PersistException& e ) // Persist Exception { cout << "PersistException caught! " << e.getString() << endl; } catch( Exception& e ) // ost::Exception { cout << "Exception caught! " << e.getString() << endl; } catch( ios::failure& e ) // ios:exception { cout << "ios::failure exception caught! " << e.what() << endl; } catch( exception e ) // general library exception { cout << "std::exception caught! " << e.what() << endl; } #endif return 0; } _______________________________________________ Bug-commoncpp mailing list Bug-commoncpp@gnu.org http://lists.gnu.org/mailman/listinfo/bug-commoncpp