Subject: [Boost-bugs] [Boost C++ Libraries] #4536: serializing diamond shaped classes using virtual inheritance
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2010-08-12 22:16:22
#4536: serializing diamond shaped classes using virtual inheritance
--------------------------------------------------------+-------------------
Reporter: Hanyu Li <hli@â¦> | Owner: ramey
Type: Bugs | Status: new
Milestone: Boost 1.44.0 | Component: serialization
Version: Boost 1.39.0 | Severity: Problem
Keywords: virtual inheritance diamond shaped classes |
--------------------------------------------------------+-------------------
I am having some trouble with serializing diamond shaped classes which are
using virtual inheritance with boost version 1.39 and above.
Compile the following problem on Visual Studio 2008 is ok but run the
program will result an assert in base_object.hpp around line 103
return static_cast<type &>(d);
/*start of the sample program*/
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/static_assert.hpp>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <string>
#include <boost/serialization/map.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/export.hpp>
#include <cstddef> // NULL
#include <fstream>
#include <iostream>
#include <boost/config.hpp>
#include <cstdio> // remove
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::remove;
}
#endif
#define DECLARE_BOOST_SERIALIZATION_SPECIALIZE() \
template<class Archive> void serialize(Archive &ar, const unsigned int
version); \
template<class Archive> void doSerialize(Archive &ar, const unsigned
int version); \
template<> void serialize(boost::archive::xml_iarchive &ar, const
unsigned int version){doSerialize((ar),version); } \
template<> void serialize(boost::archive::xml_oarchive &ar, const
unsigned int version){doSerialize((ar),version);}
#define DECLARE_BOOST_SERIALIZATION_GENERIC() \
template<class Archive> void serialize(Archive &ar, const unsigned int
version) {doSerialize(ar,version); } \
template<class Archive> void doSerialize(Archive &ar, const unsigned
int version);
class B_GraphObject {
public:
B_GraphObject() : m_objectId(0) {}
B_GraphObject(int i) : m_objectId(i)
{
}
#ifdef __SSONESERIALIZEINTERFACE__
DECLARE_BOOST_SERIALIZATION_GENERIC()
#else
DECLARE_BOOST_SERIALIZATION_SPECIALIZE()
#endif
bool operator==(const B_GraphObject& another) const
{
return m_objectId == another.m_objectId;
}
// make polymorphic by marking at least one function virtual
virtual ~B_GraphObject() {};
private:
int m_objectId;
};
template<class Archive>
void B_GraphObject::doSerialize(Archive &ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(m_objectId);
}
class B_GraphNode : virtual public B_GraphObject {
public:
B_GraphNode(){}
B_GraphNode(int i) : B_GraphObject(i),
m_nodeWeigth(i+1){}
#ifdef __SSONESERIALIZEINTERFACE__
DECLARE_BOOST_SERIALIZATION_GENERIC()
#else
DECLARE_BOOST_SERIALIZATION_SPECIALIZE()
#endif
private:
double m_nodeWeigth;
};
template<class Archive>
void B_GraphNode::doSerialize(Archive &ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(B_GraphObject);
ar & BOOST_SERIALIZATION_NVP(m_nodeWeigth);
}
class B_GraphNode2 : virtual public B_GraphObject {
public:
B_GraphNode2(){}
B_GraphNode2(int i) : B_GraphObject(i+1),
m_nodeWeigth(i+2){
}
#ifdef __SSONESERIALIZEINTERFACE__
DECLARE_BOOST_SERIALIZATION_GENERIC()
#else
DECLARE_BOOST_SERIALIZATION_SPECIALIZE()
#endif
private:
double m_nodeWeigth;
};
template<class Archive>
void B_GraphNode2::doSerialize(Archive &ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(B_GraphObject);
ar & BOOST_SERIALIZATION_NVP(m_nodeWeigth);
}
class B_GraphChildNode : public B_GraphNode,
public B_GraphNode2 {
public:
B_GraphChildNode() {}
B_GraphChildNode(int i) : B_GraphNode(i), B_GraphNode2(i+2),
m_nodeWeigth(i+10){}
public:
#ifdef __SSONESERIALIZEINTERFACE__
DECLARE_BOOST_SERIALIZATION_GENERIC()
#else
DECLARE_BOOST_SERIALIZATION_SPECIALIZE()
#endif
private:
double m_nodeWeigth;
};
BOOST_CLASS_EXPORT(B_GraphChildNode)
template<class Archive>
void B_GraphChildNode::doSerialize(Archive &ar, const unsigned int
version)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(B_GraphNode);
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(B_GraphNode2);
ar & BOOST_SERIALIZATION_NVP(m_nodeWeigth);
}
int main()
{
const char*testfile = "diamond.xml";
B_GraphChildNode *B_GraphChildNodePtr = new B_GraphChildNode( 3 );
const B_GraphObject* bp = B_GraphChildNodePtr;
{
std::ofstream ofs(testfile);
boost::archive::xml_oarchive oa(ofs);
oa << BOOST_SERIALIZATION_NVP(bp);
}
B_GraphObject* bp2;
{
std::ifstream ifs(testfile);
boost::archive::xml_iarchive ia(ifs);
ia >> BOOST_SERIALIZATION_NVP(bp2);
}
return 0;
}
/*end of the sample program*/
If I compile the program by defining __SSONESERIALIZEINTERFACE__ in Visual
Studio 2008, the program runs ok.
Using boost version 1.38, the sample program runs ok regardless defining
__SSONESERIALIZEINTERFACE__ or not.
There must be something changed in 1.39 which is causing the problem.
Thanks,
Hanyu
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/4536> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:04 UTC