Boost logo

Boost :

Subject: Re: [boost] [Serialization] Bizarre bug
From: Jarl Lindrud (jarl.lindrud_at_[hidden])
Date: 2009-08-10 04:01:49


Robert Ramey <ramey <at> rrsd.com> writes:

> > -----------------------------------------
> >
> > * If one program writes archives like this:
> >
> > ar & vec; // vec is a std::vector<char>
> >
> > , it is then impossible to reliably load that archive in another
> > program, unless one is aware of the entire compile-time content of
> > the first program.
>
> Nope. The only time a problem can occur if one does
>
> ar & vec; // vec is a std::vector<char>
>
> In the saving program and
>
> ar & p_vec; // vec is a * std::vector<char>
>
> in the loading progam.

Robert, that's manifestly incorrect. I have appended 3 well-formed programs,
A1, A2, and B, to this post. B can read archives from A1, but it *cannot* read
archives from A2. If you don't believe me, then please run the programs
yourself. The only difference between A1 and A2 is compile-time instantiation,
of code that is never executed.

>
> Making matters worse, the archive
>
> > format change is compatibility- breaking.
>
> Only for collections of primitives.
>

So we do agree that compatibility does break, due to compile-time instantiation.

>
> I would use "concievable" rather than "likely". In fact, I can't think
> of any real program where this could occur without there being
> some other error that would also prevent this program from
> functioning.
>

Do you consider there to be any errors in either A1, A2 or B?

If you were to implement a generic IPC marshalling layer, you would end up with
the kind of code that A1, A2, and B contain. IPC serialization is a bit
different from file-based serialization, in that serialization and
deserialization generally take place in different programs.

Another wrinkle in IPC serialization, is that one program may contain only
serialization code for a type T (and not deserialization), while another
program may contain only deserialization code for type T (and not
serialization). If that makes the programs ill-formed in your view, then I
guess one would have to conclude that B.Ser. is not an appropriate choice for
IPC applications.

Regards,
Jarl

----------------------------------
// A1

#include <fstream>

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/vector.hpp>

int main()
{
        std::vector<char> vec(25, 'A');
        std::ofstream fout("A.txt");
        boost::archive::text_oarchive(fout) & vec;
        return 0;
}

----------------------------------
// A2

#include <fstream>

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/vector.hpp>

template<typename Archive>
struct X
{
        template<typename T>
        void operator<<(const T &t)
        {
                Archive &archive = (*(Archive *) NULL);
                archive << t;
        }

        template<typename T>
        void operator>>(T &t)
        {
                Archive &archive = (*(Archive *) NULL);
                archive >> t;
        }
};

// This function is instantiated by the compiler, but never executed.
void dummy()
{
        typedef boost::archive::text_iarchive IArchive;
        typedef boost::archive::text_oarchive OArchive;
        std::vector<char> *pt = NULL;

        X<OArchive> & oar = * (X<OArchive> *) NULL;
        oar << pt;
                
        X<IArchive> & iar = * (X<IArchive> *) NULL;
        iar >> pt;
}

int main()
{
        std::vector<char> vec(25, 'A');
        std::ofstream fout("A.txt");
        boost::archive::text_oarchive(fout) & vec;
        return 0;
}

----------------------------------
// B

#include <fstream>

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/vector.hpp>

int main()
{
        std::vector<char> vec;
        std::ifstream fin("A.txt");
        
        // If A1 produced the archive, this line succeeds.
        // If A2 produced the archive, this line will silently fail.
        boost::archive::text_iarchive(fin) & vec;
        
        return 0;
}

----------------------------------


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk