Boost C++ Libraries: Ticket #4536: serializing diamond shaped classes using virtual inheritance https://svn.boost.org/trac10/ticket/4536 <p> I am having some trouble with serializing diamond shaped classes which are using virtual inheritance with boost version 1.39 and above. </p> <p> 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 </p> <p> return static_cast&lt;type &amp;&gt;(d); </p> <p> /*start of the sample program*/ #include &lt;boost/archive/xml_iarchive.hpp&gt; #include &lt;boost/archive/xml_oarchive.hpp&gt; #include &lt;boost/serialization/nvp.hpp&gt; #include &lt;boost/static_assert.hpp&gt; #include &lt;iomanip&gt; #include &lt;iostream&gt; #include &lt;fstream&gt; #include &lt;string&gt; </p> <p> #include &lt;boost/serialization/map.hpp&gt; #include &lt;boost/serialization/utility.hpp&gt; #include &lt;boost/serialization/base_object.hpp&gt; #include &lt;boost/serialization/nvp.hpp&gt; #include &lt;boost/archive/xml_iarchive.hpp&gt; #include &lt;boost/archive/xml_oarchive.hpp&gt; #include &lt;boost/serialization/export.hpp&gt; </p> <p> #include &lt;cstddef&gt; <em> NULL #include &lt;fstream&gt; #include &lt;iostream&gt; </em></p> <p> #include &lt;boost/config.hpp&gt; #include &lt;cstdio&gt; <em> remove #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ </em></p> <blockquote> <p> using ::remove; </p> </blockquote> <p> } #endif </p> <p> #define DECLARE_BOOST_SERIALIZATION_SPECIALIZE() \ </p> <blockquote> <p> template&lt;class Archive&gt; void serialize(Archive &amp;ar, const unsigned int version); \ template&lt;class Archive&gt; void doSerialize(Archive &amp;ar, const unsigned int version); \ template&lt;&gt; void serialize(boost::archive::xml_iarchive &amp;ar, const unsigned int version){doSerialize((ar),version); } \ template&lt;&gt; void serialize(boost::archive::xml_oarchive &amp;ar, const unsigned int version){doSerialize((ar),version);} </p> </blockquote> <p> #define DECLARE_BOOST_SERIALIZATION_GENERIC() \ </p> <blockquote> <p> template&lt;class Archive&gt; void serialize(Archive &amp;ar, const unsigned int version) {doSerialize(ar,version); } \ template&lt;class Archive&gt; void doSerialize(Archive &amp;ar, const unsigned int version); </p> </blockquote> <p> class B_GraphObject { public: </p> <blockquote> <p> B_GraphObject() : m_objectId(0) {} B_GraphObject(int i) : m_objectId(i) { } </p> </blockquote> <p> #ifdef <span class="underline">SSONESERIALIZEINTERFACE</span> </p> <p> DECLARE_BOOST_SERIALIZATION_GENERIC() #else DECLARE_BOOST_SERIALIZATION_SPECIALIZE() #endif </p> <blockquote> <p> bool operator==(const B_GraphObject&amp; another) const { </p> <blockquote> <p> return m_objectId == another.m_objectId; </p> </blockquote> <p> } <em> make polymorphic by marking at least one function virtual virtual ~B_GraphObject() {}; </em></p> </blockquote> <p> private: </p> <blockquote> <p> int m_objectId; </p> </blockquote> <p> }; </p> <p> template&lt;class Archive&gt; void B_GraphObject::doSerialize(Archive &amp;ar, const unsigned int version) { </p> <blockquote> <p> ar &amp; BOOST_SERIALIZATION_NVP(m_objectId); </p> </blockquote> <p> } </p> <p> class B_GraphNode : virtual public B_GraphObject { public: </p> <blockquote> <p> B_GraphNode(){} B_GraphNode(int i) : B_GraphObject(i), </p> <blockquote> <p> m_nodeWeigth(i+1){} </p> </blockquote> </blockquote> <p> #ifdef <span class="underline">SSONESERIALIZEINTERFACE</span> DECLARE_BOOST_SERIALIZATION_GENERIC() #else DECLARE_BOOST_SERIALIZATION_SPECIALIZE() </p> <p> #endif </p> <p> private: </p> <blockquote> <p> double m_nodeWeigth; </p> </blockquote> <p> }; </p> <p> template&lt;class Archive&gt; void B_GraphNode::doSerialize(Archive &amp;ar, const unsigned int version) { </p> <blockquote> <p> ar &amp; BOOST_SERIALIZATION_BASE_OBJECT_NVP(B_GraphObject); </p> <blockquote> <p> ar &amp; BOOST_SERIALIZATION_NVP(m_nodeWeigth); </p> </blockquote> </blockquote> <p> } </p> <p> class B_GraphNode2 : virtual public B_GraphObject { public: </p> <blockquote> <p> B_GraphNode2(){} B_GraphNode2(int i) : B_GraphObject(i+1), </p> <blockquote> <p> m_nodeWeigth(i+2){ </p> </blockquote> </blockquote> <p> } #ifdef <span class="underline">SSONESERIALIZEINTERFACE</span> DECLARE_BOOST_SERIALIZATION_GENERIC() #else DECLARE_BOOST_SERIALIZATION_SPECIALIZE() #endif private: </p> <blockquote> <p> double m_nodeWeigth; </p> </blockquote> <p> }; </p> <p> template&lt;class Archive&gt; void B_GraphNode2::doSerialize(Archive &amp;ar, const unsigned int version) { </p> <blockquote> <p> ar &amp; BOOST_SERIALIZATION_BASE_OBJECT_NVP(B_GraphObject); </p> <blockquote> <p> ar &amp; BOOST_SERIALIZATION_NVP(m_nodeWeigth); </p> </blockquote> </blockquote> <p> } </p> <p> class B_GraphChildNode : public B_GraphNode, </p> <blockquote> <p> public B_GraphNode2 { </p> </blockquote> <p> public: </p> <blockquote> <p> B_GraphChildNode() {} B_GraphChildNode(int i) : B_GraphNode(i), B_GraphNode2(i+2), m_nodeWeigth(i+10){} </p> </blockquote> <p> public: #ifdef <span class="underline">SSONESERIALIZEINTERFACE</span> DECLARE_BOOST_SERIALIZATION_GENERIC() #else DECLARE_BOOST_SERIALIZATION_SPECIALIZE() #endif private: </p> <blockquote> <p> double m_nodeWeigth; </p> </blockquote> <p> }; </p> <p> BOOST_CLASS_EXPORT(B_GraphChildNode) </p> <p> template&lt;class Archive&gt; void B_GraphChildNode::doSerialize(Archive &amp;ar, const unsigned int version) { </p> <blockquote> <p> ar &amp; BOOST_SERIALIZATION_BASE_OBJECT_NVP(B_GraphNode); ar &amp; BOOST_SERIALIZATION_BASE_OBJECT_NVP(B_GraphNode2); ar &amp; BOOST_SERIALIZATION_NVP(m_nodeWeigth); </p> </blockquote> <p> } </p> <p> int main() { </p> <blockquote> <p> const char*testfile = "diamond.xml"; </p> </blockquote> <blockquote> <p> B_GraphChildNode *B_GraphChildNodePtr = new B_GraphChildNode( 3 ); </p> </blockquote> <blockquote> <p> const B_GraphObject* bp = B_GraphChildNodePtr; { </p> <blockquote> <p> std::ofstream ofs(testfile); boost::archive::xml_oarchive oa(ofs); oa &lt;&lt; BOOST_SERIALIZATION_NVP(bp); </p> </blockquote> <p> } </p> </blockquote> <blockquote> <p> B_GraphObject* bp2; { </p> <blockquote> <p> std::ifstream ifs(testfile); boost::archive::xml_iarchive ia(ifs); ia &gt;&gt; BOOST_SERIALIZATION_NVP(bp2); </p> </blockquote> <p> } </p> </blockquote> <blockquote> <blockquote> <p> return 0; </p> </blockquote> </blockquote> <p> } /*end of the sample program*/ </p> <p> If I compile the program by defining <span class="underline">SSONESERIALIZEINTERFACE</span> in Visual Studio 2008, the program runs ok. </p> <p> Using boost version 1.38, the sample program runs ok regardless defining <span class="underline">SSONESERIALIZEINTERFACE</span> or not. </p> <p> There must be something changed in 1.39 which is causing the problem. </p> <p> Thanks, Hanyu </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/4536 Trac 1.4.3 Robert Ramey Fri, 13 Aug 2010 03:45:00 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/4536#comment:1 https://svn.boost.org/trac10/ticket/4536#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> There have been changes in 1.44 - soon to be released which I believe will address this issue. So for now I'm going to mark this as fixed. Please feel free to re-open this if you have the problem after testing with the version 1.44. </p> <p> Robert Ramey </p> Ticket