Opened 15 years ago

Closed 15 years ago

Last modified 15 years ago

#1267 closed Bugs (fixed)

Assertion `new_cid == cid' failed in basic_iarchive

Reported by: mbergin@… 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)

test_exported.cpp.gz (1.2 KB ) - added by mbergin@… 15 years ago.

Download all attachments as: .zip

Change History (10)

comment:1 by mbergin@…, 15 years ago

I am having trouble attaching the test case; Trac is telling me it is spam.

by mbergin@…, 15 years ago

Attachment: test_exported.cpp.gz added

comment:2 by mbergin@…, 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>

in reply to:  description comment:3 by gwossum@…, 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 anonymous, 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 gwossum@…, 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 mbergin@…, 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 Robert Ramey, 15 years ago

Status: newassigned

comment:8 by Robert Ramey, 15 years ago

Resolution: fixed
Status: assignedclosed

resolved by folding T to const T in serialization/is_abstract

comment:9 by anonymous, 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.

Note: See TracTickets for help on using tickets.