#1267 closed Bugs (fixed)
Assertion `new_cid == cid' failed in basic_iarchive
Reported by: | Owned by: | Robert Ramey | |
---|---|---|---|
Milestone: | To Be Determined | Component: | serialization |
Version: | Boost 1.34.1 | Severity: | Problem |
Keywords: | Cc: | troy@… |
Description
This has previously been reported on http://lists.boost.org/boost-users/2006/01/16604.php
This bug seems to appear when a class containing a polymorphic object pointer is serialized with separate save/load methods and the BOOST_IS_ABSTRACT() macro is used on the polymorphic base.
I've attached a simpler test case which is another modified version of test_exported.cpp based on Troy D. Straszheim's version in the above mailing list post. It fails on GCC 3.2.3 and 3.4.5 (Linux x86) with:
../../../libs/serialization/src/basic_iarchive.cpp:466: const boost::archive::detail::basic_pointer_iserializer* boost::archive::detail::basic_iarchive_impl::load_pointer( boost::archive::detail::basic_iarchive&, void*&, const boost::archive::detail::basic_pointer_iserializer*, const boost::archive::detail::basic_pointer_iserializer*(*)(const boost::serialization::extended_type_info&)): Assertion `new_cid == cid' failed.
Attachments (1)
Change History (10)
comment:1 by , 15 years ago
by , 15 years ago
Attachment: | test_exported.cpp.gz added |
---|
comment:2 by , 15 years ago
Also tested on VC8 and fails. The serialized output of the above test case is below. Are the class IDs being output in the wrong order?
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <!DOCTYPE boost_serialization> <boost_serialization signature="serialization::archive" version="4"> <c class_id="0" tracking_level="0" version="0"> <px class_id="2" class_name="polymorphic_derived" tracking_level="1" version="0" object_id="_0"> <polymorphic_base class_id="1" tracking_level="1" version="0" object_id="_1"></polymorphic_base> </px> </c> </boost_serialization>
comment:3 by , 15 years ago
I've encountered the same problem with g++ 3.2.3. With g++ 3.2.3, it occurs any time I try to serialize a thaw a derived class through an abstract base class pointer, whether or not separate save and load methods are used. Dropping the BOOST_CLASS_EXPORT() for the abstract base class does NOT fix the problem. Only making the base class non-abstract makes the problem go away, which isn't always an appealing option.
As a curious note, I have a class heirarchy that involves an abstract base class A, an abstract subclass of A (B), and a several concrete subclasses of B. I encounter issues if A is abstract, but if I make A concrete but B is still abstract, I don't get any problems.
comment:4 by , 15 years ago
The short answer is:
BOOST_IS_ABSTRACT(const polymorphic_base)
Rake are hidden in basic_xml_oarchive::save_override(nvp<T>&) method:
template<class T> void save_override( #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING const #endif ::boost::serialization::nvp<T> & t, int ){ this->This()->save_start(t.name()); archive::save(* this->This(), t.const_value()); /// CONST!! this->This()->save_end(t.name()); }
nvp<T>::const_value() method allways returns constant reference and it doesn't matter what type you have passed to nvp<T>'s ctor.
const T & const_value() const { return *(this->second); }
So, in save_pointer_type::register_type method() the serialization::is_abstract<T> check is always being applied not to the constant type. IMHO it is better to fix serialization::is_abstract, but as a temporary solution additional BOOST_IS_ABSTRACT directive for constant type can be used.
P.S. I investigated this problem with boost-1.33.1 using GCC 3.4.5 (MinGW) and Intel 8.0 compiler.
comment:5 by , 15 years ago
Tried the BOOST_CLASS_EXPORT(const PolymorphicBase) with boost-1.33.1 and gcc 3.2.3. Got a static assertion at archive/detail/iserializer.hpp line 610. The comment around this suggests the assertion is due to gcc 3.2.3 not having correct function template ordering. Could this be part of the problem with gcc 3.2.3?
comment:6 by , 15 years ago
This works for me on GCC3.2.3, but it's important to note you need to do both BOOST_IS_ABSTRACT(polymorphic_base) BOOST_IS_ABSTRACT(const polymorphic_base) for it to compile.
comment:7 by , 15 years ago
Status: | new → assigned |
---|
comment:8 by , 15 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
resolved by folding T to const T in serialization/is_abstract
comment:9 by , 15 years ago
I was curious as to what the fix was (as it isn't available in 1.34.1). For those interested: I've pinned it down to r42254.
I am having trouble attaching the test case; Trac is telling me it is spam.