[Boost-bugs] [ boost-Bugs-1255637 ] 1.33RC2: archive_pointer_[o/i]serializer assert problem

Bugs item #1255637, was opened at 2005-08-10 02:36 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=107586&aid=1255637&group_id=7586 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: serialization Group: None Status: Open Resolution: None Priority: 5 Submitted By: Nobody/Anonymous (nobody) Assigned to: Robert Ramey (ramey) Summary: 1.33RC2: archive_pointer_[o/i]serializer assert problem Initial Comment: Hello again, FYI .. i read the boost mailing list, so posting anwers there is ok for me ;-) I made some progress after reading "rationale" though some things still give headaches. I have polymorphic class hierarchy which gets serialized thru base ptrs (along with shared_ptr stuff). When using portable_binary_oarchive/iarchive (taken from boost example) an assert() triggers which raises some questions. oserializer.hpp: -------------- snip -------------- // sice true_type is valid, and this only gets made if the // pointer oserializer object has been created, this should never fail bpos_ptr = archive_pointer_oserializer<Archive>::find(* true_type); assert(NULL != bpos_ptr); if(NULL == bpos_ptr) boost::throw_exception( archive_exception(archive_exception::unregistered_class) ); -------------- snip -------------- "should never fail" seems to fail and i dont know why ;-( (long callstack omitted)
test_protocollayers.exe!boost::archive::detail::save_pointer_type<portable_binary_oarchive,xxx::ProtocolHeader const *>::polymorphic<xxx::ProtocolHeader>::save(portable_binary_oarchive & ar={...}, const xxx::ProtocolHeader & t={...}, const boost::archive::detail::basic_pointer_oserializer * bpos_ptr=0x00000000) Line 416 C++ test_protocollayers.exe!boost::archive::detail::save_pointer_type<portable_binary_oarchive,xxx::ProtocolHeader const *>::save<xxx::ProtocolHeader>(portable_binary_oarchive & ar={...}, const xxx::ProtocolHeader & t={...}, const boost::archive::detail::basic_pointer_oserializer * bpos_ptr=0x00000000) Line 438 + 0x11 C++ test_protocollayers.exe!boost::archive::detail::save_pointer_type<portable_binary_oarchive,xxx::ProtocolHeader const *>::invoke(portable_binary_oarchive & ar={...}, const xxx::ProtocolHeader * const t=0x00680698) Line 466 + 0x11 C++ test_protocollayers.exe!boost::archive::save<portable_binary_oarchive,xxx::ProtocolHeader const *>(portable_binary_oarchive & ar={...}, const xxx::ProtocolHeader * const & t=0x00680698) Line 535 + 0xf C++ The classes usually contain: "template<class Archive> void serialize( Archive & ar, const unsigned int /* version */)" stuff, along with explicit: "boost::serialization::void_cast_register<Derived, Base>(0,0);" in ctors (or it doesnt work). "this_type" = abstract base "true_type" = derived both classes are successfully retrieved via type info (registered class). The "vp = serialization::void_downcast(*true_type, *this_type, &t);" works too (because the void_cast_register). But it doesnt find appropriate basic_pointer_oserializer .... I placed a breakpoint at "basic_serializer_map::insert(const basic_serializer * bs)" to see what types get registered at startup (initterm ctors). There are indeed registrations but some (derived) types are missing. What gives? BTW ... could you make "portable_binary_oarchive" (and iarchive) included in available boost archive types? I find it useful because serialization is used in cross platform protocol stacks (little vs. big endian archs). Is there any chance to reduce binary overhead due to registration data (shared_ptr/type info ... binary size almost doubled due to contained type info in small payloads). Can stringified type info be omitted/shortened (i use hierachial namespaces which blow the length)? Regards, A. Focht ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=107586&aid=1255637&group_id=7586 ------------------------------------------------------- SF.Net email is Sponsored by the Better Software Conference & EXPO September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf _______________________________________________ Boost-bugs mailing list Boost-bugs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/boost-bugs

SourceForge.net wrote:
I made some progress after reading "rationale" though some things still give headaches.
Could you expand on this? I am curious as to how this works for users.
I have polymorphic class hierarchy which gets serialized thru base ptrs (along with shared_ptr stuff). When using portable_binary_oarchive/iarchive (taken from boost example) an assert() triggers which raises some questions.
oserializer.hpp:
-------------- snip --------------
// sice true_type is valid, and this only gets made if the // pointer oserializer object has been created, this should never fail bpos_ptr = archive_pointer_oserializer<Archive>::find(* true_type); assert(NULL != bpos_ptr); if(NULL == bpos_ptr) boost::throw_exception(
archive_exception(archive_exception::unregistered_class) );
-------------- snip --------------
When compiled with debug mode - this traps an assert. When compiled for release, it throws exception "unregistered class". You should be trapping the archive exceptions. The basic problem is that derived classes have to be "registered" or "exported" in order for the serialization system to know about them. Look in the documentation for the exceptions where you will find an explanation of this error and how to address it.
The classes usually contain:
"template<class Archive> void serialize( Archive & ar, const unsigned int /* version */)"
stuff, along with explicit:
"boost::serialization::void_cast_register<Derived, Base>(0,0);"
in ctors (or it doesnt work).
"this_type" = abstract base "true_type" = derived
it should be necessary to explicitly call void_cast_register only in unusual cases. The common case is for the derived class to inlcude ar << base_object<base_class>(*this) which invokes void_cast_register. The only time I've had to call void_cast_register explicitly is when I don't want to have a serialization function in the base class itself. But this has been a rare case. So a) first try using base_object. If the base class doesn't have any data, include an empty serialize function. b) once the above works, if the base class doesn't have any data, replace base_object with void_cast_register<Base, Derived>
BTW ... could you make "portable_binary_oarchive" (and iarchive) included in available boost archive types? I find it useful because serialization is used in cross platform protocol stacks (little vs. big endian archs).
this started out as an example of how to derived from a pre-existing archive type. Its not really ready for prime time as a) it doesn't support a portable format for floats and doubles b) it depends upon endian.hpp which doesn't seem to be correctly implemented for all compilers / machines that boost works with. c) If I make this "official", I would have to make another example.
Is there any chance to reduce binary overhead due to registration data (shared_ptr/type info ... binary size almost doubled due to contained type info in small payloads).
Can stringified type info be omitted/shortened (i use hierachial namespaces which blow the length)?
I believe you could address these issues by using the "registration" method rather then "export" to commuincate derived classes to the serialization library. These place only a small digit into the library. Robert Ramey
participants (2)
-
Robert Ramey
-
SourceForge.net