id,summary,reporter,owner,description,type,status,milestone,component,version,severity,resolution,keywords,cc 3604,Access violation on diamond inheritance,kondo@…,Robert Ramey,"= phenomenon = When I serialize the sub-class via virtual base class, some BOOST_CLASS_EXPORT order makes access violation. main.cpp(attached file) reproduce these behavior on VC++ ver 9. Please check it. Classes structure is structure.png(attached file). If BOOST_CLASS_EXPORT order is Target, Sub1, the error doesn't occur. If BOOST_CLASS_EXPORT order is Sub1, Target, the error occurs. main.cpp {{{ #!cpp #if 0 // OK BOOST_CLASS_EXPORT(Target) BOOST_CLASS_EXPORT(Sub1) #else // NG BOOST_CLASS_EXPORT(Sub1) BOOST_CLASS_EXPORT(Target) #endif }}} = analysis = I checked the behavior of void_caster::recursive_register step by step. boost_1_40_0\libs\serialization\src\void_cast.cpp {{{ #!cpp // implementation of void caster base class BOOST_SERIALIZATION_DECL(void) void_caster::recursive_register(bool includes_virtual_base) const { void_cast_detail::set_type & s = void_cast_detail::void_caster_registry::get_mutable_instance(); s.insert(this); // generate all implied void_casts. void_cast_detail::set_type::const_iterator it; for(it = s.begin(); it != s.end(); ++it){ if(* m_derived == * (*it)->m_base) new void_caster_shortcut( // match A (*it)->m_derived, m_base, m_difference + (*it)->m_difference, includes_virtual_base ); if(* (*it)->m_derived == * m_base) new void_caster_shortcut( // match B m_derived, (*it)->m_base, m_difference + (*it)->m_difference, includes_virtual_base ); } }}} ---- OK Case r-level means recursive level(not so important). 'No' means registration order(not internal order of container set). ||No||r-level||virtual base||Derived||Base||Action||!OverWrite|| ||0||||false||Target||Sub2||-|||| ||1||||false||Sub1||Mid1||-|||| ||2||||false||Sub1||Mid2||-|||| ||3||||false||Sub2||Mid1||match A Sub2 No.0,add No.4|||| ||4||1||false||Target||Mid1||-|||| ||5||||false||Sub2||Mid2||match A Sub2 No.0,add No.6|||| ||6||1||false||Target||Mid2||-|||| ||7||||true||Mid1||VBase||match A Mid1 No.1,add No.8|||| ||||||||||||match A Mid1 No.3 add No.9|||| ||||||||||||match A Mid1 No.4 add No.11|||| ||8||1||true||Sub1||VBase||-|||| ||9||1||true||Sub2||VBase||match A Sub2 No.0,add No.10|||| ||10||2||true||Target||VBase||-|||| ||11||2||true||Target||VBase||-||No.10|| ||12||||true||Mid2||VBase||match A Mid2 No.2,add No.13|||| ||||||||||||match A Mid2 No.5,add No.14|||| ||||||||||||match A Mid2 No.6,add No.16|||| ||13||1||true||Sub1||Vbase||-||No.8|| ||14||1||true||Sub2||VBase||match A Sub2 No.0,add No.15||No.9|| ||15||2||true||Target||VBase||-||No.10|| ||16||1||true||Target||VBase||-||No.10|| Result (focus on m_includes_virtual_base) values of s {{{ #!cpp void_cast_detail::set_type & s = void_cast_detail::void_caster_registry::get_mutable_instance(); }}} {{{ [0] 0x004add48 t const boost::serialization::void_cast_detail::void_caster * [1] 0x004add7c t const boost::serialization::void_cast_detail::void_caster * [2] 0x004adb7c t const boost::serialization::void_cast_detail::void_caster * [3] 0x004adbb0 t const boost::serialization::void_cast_detail::void_caster * [4] 0x003981e0 {m_includes_virtual_base=true } const boost::serialization::void_cast_detail::void_caster * [5] 0x004adce0 t const boost::serialization::void_cast_detail::void_caster * [6] 0x004add14 t const boost::serialization::void_cast_detail::void_caster * [7] 0x00398298 {m_includes_virtual_base=true } const boost::serialization::void_cast_detail::void_caster * [8] 0x00397a18 {m_includes_virtual_base=false } const boost::serialization::void_cast_detail::void_caster * [9] 0x003943c8 {m_includes_virtual_base=false } const boost::serialization::void_cast_detail::void_caster * [10] 0x004adb48 t const boost::serialization::void_cast_detail::void_caster * [11] 0x00398350 {m_includes_virtual_base=true } const boost::serialization::void_cast_detail::void_caster * }}} ---- NG Case ||No||r-level||vb||Derived||Base||Action||!OverWrite|| ||0||||false||Sub1||Mid1||-|||| ||1||||false||Sub1||Mid2||-|||| ||2||||false||Target||Sub2||-|||| ||3||||true||Mid1||VBase||match A Mid1 No.0,add No.4|||| ||4||1||true||Sub1||VBase||-|||| ||5||||true||Mid2||VBase||match A Mid2 No.1,add No.6|||| ||6||1||true||Sub1||VBase||-||No.4|| ||7||||false||Sub2||Mid1||match B Mid1 No.3,add No.8|||| ||||||||||||match A Sub2 No.2,add No.10|||| ||8||1||false||Sub2||VBase||match A Sub2 No.2,add No.9|||| ||9||2||false||Target||VBase||-|||| ||10||1||false||Target||Mid1||match B Mid1 No.3,add No.11|||| ||11||2||false||Target||VBase||-||No.9|| ||12||||false||Sub2||Mid2||match B Mid2 No.5,add No.13|||| ||||||||||||match A Sub2 No.2,add No.15|||| ||13||1||false||Sub2||VBase||match A Sub2 No.2,add No.14||No.8|| ||14||2||false||Target||VBase||-||No.9|| ||15||1||false||Target||Mid2||match B Mid2 No.5,add No.16|||| ||16||2||false||Target||VBase||-||No.9|| Result (focus on m_includes_virtual_base) {{{ [0] 0x004adce0 t const boost::serialization::void_cast_detail::void_caster * [1] 0x004add14 t const boost::serialization::void_cast_detail::void_caster * [2] 0x004adb48 t const boost::serialization::void_cast_detail::void_caster * [3] 0x004adb7c t const boost::serialization::void_cast_detail::void_caster * [4] 0x00397a18 {m_includes_virtual_base=true } const boost::serialization::void_cast_detail::void_caster * [5] 0x004add48 t const boost::serialization::void_cast_detail::void_caster * [6] 0x004add7c t const boost::serialization::void_cast_detail::void_caster * [7] 0x00398190 {m_includes_virtual_base=false } const boost::serialization::void_cast_detail::void_caster * [8] 0x00398300 {m_includes_virtual_base=false } const boost::serialization::void_cast_detail::void_caster * [9] 0x00398540 {m_includes_virtual_base=false } const boost::serialization::void_cast_detail::void_caster * [10] 0x004adbb0 t const boost::serialization::void_cast_detail::void_caster * [11] 0x00398248 {m_includes_virtual_base=false } const boost::serialization::void_cast_detail::void_caster * }}} ---- m_includes_virtual_base is different in OK case and NG case. Probably it is the reason of access violation. I think that there is a problem in void_caster::recursive_register algorithm. ",Support Requests,closed,Boost 1.41.0,serialization,Boost 1.40.0,Not Applicable,fixed,,