Boost logo

Boost Users :

From: Robbie Morrison (robbie_at_[hidden])
Date: 2007-08-21 12:21:59


Hello all

My problem is similar to that discussed by Phil and Robert
Ramey on 'Boost - Users' back in 08-Feb-2007. Their thread
was titled "serialization stream error". Phil however did
not post back a follow up and it remains unclear as to whether
his difficulties were resolved or not. Moreover, these
discussions predate the 1.34.1 release on 24-Jul-2007 by
about five months. For my part, I have tried solving the
problem covered in this email using:

   - Boost 1.33.1 from an Ubuntu package and dated 05-Dec-2005
   - Boost 1.34.1 built from source under Ubuntu 6.10

I would like to get 'demo_shared_ptr.cpp' to run using XML
rather than text as the archive format -- as a precursor to
integrating this kind of code into an energy system
simulation.

I decided to use a step-by-step approach:

  step 1 - build and run the original 'demo_shared_ptr.cpp'
           using the original text archive format

    - therefore, remove the leading A:: and B:: from
      constructor and destructor definitions

    - comment out the following (two places):

        oa.register_type(static_cast<boost::detail::sp_counted_base_impl
          <B *, boost::checked_deleter<B> > *>(NULL));

        [as far as I could tell 'sp_counted_base_impl' no longer exists]

  step 2 - add NVP statements while retaining the text
           archive format for the time being

    - therefore, swap over all archive calls, for instance:

        // ar & x;
        ar & boost::serialization::make_nvp("x", x);

  step 3 - switch to the XML archive format

    - duly change the following headers:

        // #include <boost/archive/text_iarchive.hpp>
        // #include <boost/archive/text_oarchive.hpp>
        #include <boost/archive/xml_iarchive.hpp>
        #include <boost/archive/xml_oarchive.hpp>

    - duly change the archive objects:

        // boost::archive::text_oarchive oa(ofs);
        boost::archive::xml_oarchive oa(ofs);

Step 3 fails but only in the derived pointer code added by
David Tonge to 'demo_shared_ptr.cpp'.

A 'boost::STATIC_ASSERTION_FAILURE' is generated. Typical
error messages are given after the main body of this
posting.

At this point, I ran out of ideas. I have read the HTML
documentation and made my own notes and still can't see a
solution. Any assistance would be very gratefully received!
Note too that I only log on once per day so don't expect a
rapid turn-around for requests for details.

In addition, I will send diffs to the maintainer when I get
a satisfactory solution.

And, in passing, it is material to note that derived class B
does not fully archive its state and that there should
probably be an "ar & x" statement in its 'serialize'
definition.

For the record, here is my development environment:

  os : Ubuntu 6.10, Linux 2.6.17-12-generic
  hardware : Toshiba Tecra A2 330 laptop (purchased 27-Aug-2004)
  specs : 1.4GHz Intel Celeron M (32-bit) / 512MiB RAM / 40GB HDD / 1024x76
  gcc : gcc (GCC) 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)

I realize that this is not the latest release of Ubuntu, but
otherwise my system is fully current.

Lastly, I take it Boost.Serialization and TR1 shared
pointers (std::tr1::shared_ptr) remain incompatible at this
point in development.

Many thanks to Robert Ramey for developing Boost.Serialization.
It suits my needs to a tee, so I hope I can get this issue
resolved and move on with real coding.

best wishes
Robbie

---------------------------------
 selected error messages
---------------------------------

/usr/local/include/boost-1_34_1/boost/archive/basic_xml_oarchive.hpp:
In member function 'void
boost::archive::basic_xml_oarchive<Archive>::save_override(T&, int)
[with T = const A, Archive = boost::archive::xml_oarchive]':

/usr/local/include/boost-1_34_1/boost/archive/detail/interface_oarchive.hpp:79:
instantiated from 'Archive&
boost::archive::detail::interface_oarchive<Archive>::operator<<(T&)
[with T = const A, Archive = boost::archive::xml_oarchive]'

/usr/local/include/boost-1_34_1/boost/archive/detail/interface_oarchive.hpp:87:
instantiated from 'Archive&
boost::archive::detail::interface_oarchive<Archive>::operator&(T&)
[with T = A, Archive = boost::archive::xml_oarchive]'

qdemo_shared_ptr.mod01.cpp:76:
instantiated from 'void B::serialize(Archive&, unsigned int) [with
Archive = boost::archive::xml_oarchive]'

/usr/local/include/boost-1_34_1/boost/serialization/access.hpp:109:
instantiated from 'static void
boost::serialization::access::serialize(Archive&, T&, unsigned int)
[with Archive = boost::archive::xml_oarchive, T = B]'

/usr/local/include/boost-1_34_1/boost/serialization/serialization.hpp:81:
instantiated from 'void boost::serialization::serialize(Archive&, T&,
unsigned int) [with Archive = boost::archive::xml_oarchive, T = B]'

/usr/local/include/boost-1_34_1/boost/serialization/serialization.hpp:140:
instantiated from 'void boost::serialization::serialize_adl(Archive&,
T&, unsigned int) [with Archive = boost::archive::xml_oarchive, T = B]'

/usr/local/include/boost-1_34_1/boost/archive/detail/oserializer.hpp:225:
instantiated from 'boost::archive::detail::pointer_oserializer<T,
Archive>::pointer_oserializer() [with T = B, Archive =
boost::archive::xml_oarchive]'

/usr/local/include/boost-1_34_1/boost/archive/detail/oserializer.hpp:197:
instantiated from 'const
boost::archive::detail::pointer_oserializer<B,
boost::archive::xml_oarchive>
boost::archive::detail::pointer_oserializer<B,
boost::archive::xml_oarchive>::instance'

/usr/local/include/boost-1_34_1/boost/archive/detail/oserializer.hpp:189:
instantiated from 'static const
boost::archive::detail::pointer_oserializer<T, Archive>&
boost::archive::detail::pointer_oserializer<T, Archive>::instantiate()
[with T = B, Archive = boost::archive::xml_oarchive]'

/usr/local/include/boost-1_34_1/boost/archive/detail/oserializer.hpp:514:
instantiated from 'const
boost::archive::detail::basic_pointer_oserializer&
boost::archive::detail::instantiate_pointer_oserializer(Archive*, T*)
[with Archive = boost::archive::xml_oarchive, T = B]'

/usr/local/include/boost-1_34_1/boost/archive/detail/interface_oarchive.hpp:59:
instantiated from 'const
boost::archive::detail::basic_pointer_oserializer*
boost::archive::detail::interface_oarchive<Archive>::register_type(const
T*) [with T = B, Archive = boost::archive::xml_oarchive]'

demo_shared_ptr.mod01.cpp:200: instantiated from here

/usr/local/include/boost-1_34_1/boost/archive/basic_xml_oarchive.hpp:83:
error: invalid application of 'sizeof' to incomplete type
'boost::STATIC_ASSERTION_FAILURE<false>'

---------------------------------
 my modifications
---------------------------------

$ diff -u demo_shared_ptr.cpp demo_shared_ptr.mod01.cpp

--- demo_shared_ptr.cpp 2007-08-21 11:51:35.000000000 +0200
+++ demo_shared_ptr.mod01.cpp 2007-08-21 14:44:33.000000000 +0200
@@ -9,6 +9,21 @@
 //
 // See http://www.boost.org for updates, documentation, and revision history.

+// build : $ g++ -ggdb -Wall demo_shared_ptr.mod01.cpp
+// -lboost_serialization-gcc41 -o demo_shared_ptr
+// run : $ demo_shared_ptr
+
+// ---------------------------------------------------------
+// PREPROCESSOR DIRECTIVES
+// ---------------------------------------------------------
+
+// 0 = text, 1 = text with NPV statements, 2 = xml
+#define XEONA_ARCHIVE_MODE 2
+// 0 = omit DT code, 1 = use DT code
+#define DT_CODE 1
+
+// ---------------------------------------------------------
+
 #include <iomanip>
 #include <iostream>
 #include <fstream>
@@ -17,15 +32,23 @@
 #include <cstdio> // remove
 #include <boost/config.hpp>
 #if defined(BOOST_NO_STDC_NAMESPACE)
-namespace std{
+namespace std{
     using ::remove;
 }
 #endif

-#include <boost/archive/text_oarchive.hpp>
-#include <boost/archive/text_iarchive.hpp>
+#if (XEONA_ARCHIVE_MODE >= 2)
+# include <boost/archive/xml_oarchive.hpp>
+# include <boost/archive/xml_iarchive.hpp>
+#else
+# include <boost/archive/text_oarchive.hpp>
+# include <boost/archive/text_iarchive.hpp>
+#endif
+
 #include <boost/archive/tmpdir.hpp>

+//#include <boost/serialization/base_object.hpp> // base class serialization
+
 #include <boost/serialization/shared_ptr.hpp>

 ///////////////////////////
@@ -37,12 +60,18 @@
     int x;
     template<class Archive>
     void serialize(Archive & ar, const unsigned int /* file_version */){
- ar & x;
+
+#if (XEONA_ARCHIVE_MODE >= 1)
+ ar & boost::serialization::make_nvp("x", x);
+#else
+ ar & x;
+#endif
+
     }
 public:
     static int count;
- A::A(){++count;} // default constructor
- virtual A::~A(){--count;} // default destructor
+ A(){++count;} // default constructor
+ virtual ~A(){--count;} // default destructor
 };

 BOOST_SERIALIZATION_SHARED_PTR(A)
@@ -56,12 +85,18 @@
     int x;
     template<class Archive>
     void serialize(Archive & ar, const unsigned int /* file_version */){
- ar & boost::serialization::base_object<A>(*this);
+
+#if (XEONA_ARCHIVE_MODE >= 1)
+ ar & boost::serialization::base_object<A>(*this); // problem
+#else
+ ar & boost::serialization::base_object<A>(*this);
+#endif
+
     }
 public:
     static int count;
- B::B() : A() {};
- virtual B::~B() {};
+ B() : A() {};
+ virtual ~B() {};
 };

 BOOST_SERIALIZATION_SHARED_PTR(B)
@@ -83,8 +118,30 @@

 int main(int argc, char *argv[])
 {
+ std::cout << std::endl;
+ std::cout << "xeona archive mode : "
+ << XEONA_ARCHIVE_MODE
+ << std::endl;
+
+ std::cout << "DT extension mode : "
+ << DT_CODE
+ << std::endl;
+
+#if (XEONA_ARCHIVE_MODE >= 2)
+ std::string ext = "xml";
+#else
+ std::string ext = "txt";
+#endif
+
     std::string filename(boost::archive::tmpdir());
     filename += "/testfile";
+ filename += ".";
+ filename += ext;
+
+ std::cout << "testfile : "
+ << filename
+ << "\n"
+ << std::endl;

     // create a new shared pointer to ta new object of type A
     boost::shared_ptr<A> spa(new A);
@@ -94,9 +151,21 @@
     // serialize it
     {
         std::ofstream ofs(filename.c_str());
+
+#if (XEONA_ARCHIVE_MODE >= 2)
+ boost::archive::xml_oarchive oa(ofs);
+#else
         boost::archive::text_oarchive oa(ofs);
+#endif
+
+#if (XEONA_ARCHIVE_MODE >= 1)
+ oa << boost::serialization::make_nvp("spa", spa);
+ oa << boost::serialization::make_nvp("spa1", spa1);
+#else
         oa << spa;
         oa << spa1;
+#endif
+
     }
     // reset the shared pointer to NULL
     // thereby destroying the object of type A
@@ -108,17 +177,28 @@
     {
         // open the archive
         std::ifstream ifs(filename.c_str());
+
+#if (XEONA_ARCHIVE_MODE >= 2)
+ boost::archive::xml_iarchive ia(ifs);
+#else
         boost::archive::text_iarchive ia(ifs);
+#endif

- // restore the schedule from the archive
+#if (XEONA_ARCHIVE_MODE >= 1)
+ ia >> boost::serialization::make_nvp("spa", spa);
+ ia >> boost::serialization::make_nvp("spa1", spa1);
+#else
         ia >> spa;
         ia >> spa1;
+#endif
+
     }
     display(spa, spa1);
     spa.reset();
     spa1.reset();

- std::cout << std::endl;
+#if (DT_CODE >= 1)
+
     std::cout << std::endl;
     std::cout << "New tests" << std::endl;

@@ -131,17 +211,29 @@
     // serialize it
     {
         std::ofstream ofs(filename.c_str());
+
+#if (XEONA_ARCHIVE_MODE >= 2)
+ boost::archive::xml_oarchive oa(ofs);
+#else
         boost::archive::text_oarchive oa(ofs);
+#endif
         oa.register_type(static_cast<B *>(NULL));
- oa.register_type(
- static_cast<
- boost::detail::sp_counted_base_impl<
- B *, boost::checked_deleter<B>
- > *
- >(NULL)
- );
+// oa.register_type(
+// static_cast<
+// boost::detail::sp_counted_base_impl<
+// B *, boost::checked_deleter<B>
+// > *
+// >(NULL)
+// );
+
+#if (XEONA_ARCHIVE_MODE >= 1)
+ oa << boost::serialization::make_nvp("spa", spa);
+ oa << boost::serialization::make_nvp("spa1", spa1);
+#else
         oa << spa;
         oa << spa1;
+#endif
+
     }
     // reset the shared pointer to NULL
     // thereby destroying the object of type B
@@ -153,25 +245,40 @@
     {
         // open the archive
         std::ifstream ifs(filename.c_str());
+
+#if (XEONA_ARCHIVE_MODE >= 2)
+ boost::archive::xml_iarchive ia(ifs);
+#else
         boost::archive::text_iarchive ia(ifs);
+#endif

- // restore the schedule from the archive
         ia.register_type(static_cast<B *>(NULL));
- ia.register_type(
- static_cast<
- boost::detail::sp_counted_base_impl<
- B *, boost::checked_deleter<B>
- > *
- >(NULL)
- );
+// ia.register_type(
+// static_cast<
+// boost::detail::sp_counted_base_impl<
+// B *, boost::checked_deleter<B>
+// > *
+// >(NULL)
+// );
+
+#if (XEONA_ARCHIVE_MODE >= 1)
+ ia >> boost::serialization::make_nvp("spa", spa);
+ ia >> boost::serialization::make_nvp("spa1", spa1);
+#else
         ia >> spa;
         ia >> spa1;
+#endif
+
     }
     display(spa, spa1);
+
+#endif // DT code
+
     ///////////////
- std::remove(filename.c_str());
+ // std::remove(filename.c_str());

     // obj of type A gets destroyed
     // as smart_ptr goes out of scope
     return 0;
 }
+

---
Robbie Morrison
PhD student -- policy-oriented energy system simulation
Institute for Energy Engineering (IET)
Technical University of Berlin (TU-Berlin), Germany
University email (redirected) : morrison_at_[hidden]
Webmail (preferred)           : robbie_at_[hidden]
[from IMAP client]

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net