[Boost-bugs] [Boost C++ Libraries] #4535: serializing diamond shaped classes using virtual inheritance

Subject: [Boost-bugs] [Boost C++ Libraries] #4535: serializing diamond shaped classes using virtual inheritance
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2010-08-12 22:16:20


#4535: 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/4535>
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