|
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