Boost C++ Libraries: Ticket #3079: dynamic_cast returns 0 on polymorphic serialization with weak_ptr https://svn.boost.org/trac10/ticket/3079 <h3 class="section" id="Problem">Problem</h3> <p> In multiple inheritance case, after de-serialization, failed to dynamic_cast from a data member polymorphic serialize via 2nd base class (Left) to subclass (Bottom). </p> <div class="wiki-code"><div class="code"><pre> <span class="c1">// check</span> <span class="n">Left</span> <span class="o">*</span><span class="n">pLeft</span> <span class="o">=</span> <span class="n">h2</span><span class="p">.</span><span class="n">mbl_</span><span class="p">.</span><span class="n">get</span><span class="p">();</span> <span class="n">Bottom</span> <span class="o">*</span><span class="n">pBottomFromLeft</span> <span class="o">=</span> <span class="k">dynamic_cast</span><span class="o">&lt;</span><span class="n">Bottom</span> <span class="o">*&gt;</span><span class="p">(</span><span class="n">pLeft</span><span class="p">);</span> <span class="n">Right</span> <span class="o">*</span><span class="n">pRight</span> <span class="o">=</span> <span class="n">h2</span><span class="p">.</span><span class="n">mbr_</span><span class="p">.</span><span class="n">get</span><span class="p">();</span> <span class="n">Bottom</span> <span class="o">*</span><span class="n">pBottomFromRight</span> <span class="o">=</span> <span class="k">dynamic_cast</span><span class="o">&lt;</span><span class="n">Bottom</span> <span class="o">*&gt;</span><span class="p">(</span><span class="n">pRight</span><span class="p">);</span> <span class="n">assert</span><span class="p">(</span><span class="n">pBottomFromLeft</span><span class="p">);</span> <span class="c1">// Success</span> <span class="n">assert</span><span class="p">(</span><span class="n">pBottomFromRight</span><span class="p">);</span> <span class="c1">// Fail. Comment out *1 and *2, it works corrctly.</span> </pre></div></div><h3 class="section" id="Myanalysis">My analysis</h3> <p> Class 'Bottom' has weak_ptr that point to itself. When weak_ptr member wp_ exclude serialization, dynamic_cast is success.(Comment out *1 and *2 lines.) </p> <p> I set break point (using gdb). =&gt; is position. </p> <div class="wiki-code"><div class="code"><pre><span class="k">class</span> <span class="nc">Holder</span> <span class="p">{</span> <span class="k">public</span><span class="o">:</span> <span class="n">LeftSp</span> <span class="n">mbl_</span><span class="p">;</span> <span class="c1">// shared_ptr&lt;Left&gt;</span> <span class="n">RightSp</span> <span class="n">mbr_</span><span class="p">;</span> <span class="c1">// shared_ptr&lt;Right&gt;</span> <span class="n">Holder</span><span class="p">()</span> <span class="p">{}</span> <span class="c1">// for serialize</span> <span class="n">Holder</span><span class="p">(</span><span class="n">BottomSp</span> <span class="n">l</span><span class="p">,</span> <span class="n">BottomSp</span> <span class="n">r</span><span class="p">)</span><span class="o">:</span><span class="n">mbl_</span><span class="p">(</span><span class="n">l</span><span class="p">)</span> <span class="p">,</span><span class="n">mbr_</span><span class="p">(</span><span class="n">r</span><span class="p">)</span> <span class="p">{}</span> <span class="c1">// for appli construct</span> <span class="c1">// serialize</span> <span class="k">friend</span> <span class="k">class</span> <span class="nc">boost</span><span class="o">::</span><span class="n">serialization</span><span class="o">::</span><span class="n">access</span><span class="p">;</span> <span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Archive</span><span class="o">&gt;</span> <span class="kt">void</span> <span class="n">save</span><span class="p">(</span><span class="n">Archive</span> <span class="o">&amp;</span><span class="n">ar</span><span class="p">,</span> <span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="cm">/* file_version */</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span> <span class="c1">// polymophic serialize via shared_ptr</span> <span class="n">ar</span> <span class="o">&lt;&lt;</span> <span class="n">BOOST_SERIALIZATION_NVP</span><span class="p">(</span><span class="n">mbl_</span><span class="p">);</span> <span class="c1">// polymophic serialize via shared_ptr</span> <span class="n">ar</span> <span class="o">&lt;&lt;</span> <span class="n">BOOST_SERIALIZATION_NVP</span><span class="p">(</span><span class="n">mbr_</span><span class="p">);</span> <span class="p">}</span> <span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Archive</span><span class="o">&gt;</span> <span class="kt">void</span> <span class="n">load</span><span class="p">(</span><span class="n">Archive</span> <span class="o">&amp;</span> <span class="n">ar</span><span class="p">,</span> <span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="cm">/* file_version */</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// polymophic de-serialize via shared_ptr</span> <span class="n">ar</span> <span class="o">&gt;&gt;</span> <span class="n">BOOST_SERIALIZATION_NVP</span><span class="p">(</span><span class="n">mbl_</span><span class="p">);</span> <span class="c1">// polymophic de-serialize via shared_ptr</span> <span class="n">ar</span> <span class="o">&gt;&gt;</span> <span class="n">BOOST_SERIALIZATION_NVP</span><span class="p">(</span><span class="n">mbr_</span><span class="p">);</span> <span class="o">=&gt;</span> <span class="p">}</span> <span class="n">BOOST_SERIALIZATION_SPLIT_MEMBER</span><span class="p">()</span> <span class="p">};</span> </pre></div></div><p> And, I printed below values. </p> <p> In assertion failed case, _vptr.Left is equal to _vptr.Right. </p> <pre class="wiki">(gdb) p *mbl_.px $1 = {_vptr.Left = 0x8060ba8} (gdb) p *mbr_.px $1 = {_vptr.Right = 0x8060ba8} </pre><p> But, success case (remove the member wp_'s serialization), _vptr.Left is not equal to _vptr.Right </p> <pre class="wiki">(gdb) p *mbl_.px $1 = {_vptr.Left = 0x805d1e8} (gdb) p *mbr_.px $1 = {_vptr.Right = 0x805d1f8} </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/3079 Trac 1.4.3 Takatoshi Kondo <kondo@…> Mon, 25 May 2009 13:34:08 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/3079#comment:1 https://svn.boost.org/trac10/ticket/3079#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">duplicate</span> </li> </ul> <p> I'm sorry. The operation has been mistaken. Please integrate this ticket into <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3800" title="#3800: Bugs: Repeated Example in boost::type_traits::is_base_of (closed: fixed)">#3800</a>. </p> Ticket Takatoshi Kondo <kondo@…> Mon, 25 May 2009 13:35:27 GMT <link>https://svn.boost.org/trac10/ticket/3079#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3079#comment:2</guid> <description> <p> <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3800" title="#3800: Bugs: Repeated Example in boost::type_traits::is_base_of (closed: fixed)">#3800</a> =&gt; <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3080" title="#3080: Bugs: dynamic_cast returns 0 on polymorphic serialization with weak_ptr (closed: fixed)">#3080</a> </p> </description> <category>Ticket</category> </item> </channel> </rss>