Search code examples
c++exceptionserializationboostcatch-all

boost::archive::text_iarchive constructor exception


I'm using Embarcaderro C++ Builder XE7 (which provides Boost library by default) on 64-bit Windows 7.

I find it odd, that constructor of boost::archive::text_iarchive throws some exception, as nothing seems to be misplaced. I found similar question on stackoverflow, but the problem was, constructor wasn't place in try block.

My code looks like this (note that this main() is actually function executed on button press, because I use C++ Builder. Pasting the whole code would be confusing and needless).

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <fstream>
using namespace std;

int main()
{
    int numbers1[10] , numbers2[10];
    for(int i=0; i<10; i++) {numbers1[i] = i;}

    ofstream ofs("D:/Pulpit/file.txt", ios::out | ios::trunc);
    if(!ofs.good()) return 1;
    boost::archive::text_oarchive oar(ofs); //no exception
    oar << numbers1;

    fstream ifs("D:/Pulpit/file.txt", ios::in);
    if(!ifs.good()) return 1;
    boost::archive::text_iarchive iar(ifs); //exception
    iar >> numbers2;
}

As you can see, it's just definition of iarchive, with std::ifstream parameter, which is properly opened (because of if(!ifs.good())). However I still get exception of type boost::archive::archive_exception. What's really odd is that I can't handle it in any way. Even catch(...) doesn't catch it and my program terminates.

I'm sure exception is thrown by costructor (or maybe destructor?)- everything works fine after commenting out last two lines.

Output class - oarchive - doesn't throw exceptions. It seems to serialize everything fine, but I can't read it then. If I try to use stringstreams instead of fstreams, thus excluding file failure, the same things happen.


Solution

  • You must close the output file/archive before opening it as input.

    Otherwise not the full archive will have been flushed:

    Live On Coliru

    {
        std::ofstream ofs("file.txt");
        if (!ofs.good())
            return 1;
    
        boost::archive::text_oarchive oar(ofs); // no exception
        oar << numbers1;
    }
    
    {
        std::ifstream ifs("file.txt");
        if (!ifs.good())
            return 1;
        boost::archive::text_iarchive iar(ifs); // no exception!
        iar >> numbers2;
    }
    

    The stringstream solution: Live On Coliru

    Output

    0 1 2 3 4 5 6 7 8 9