The following example works on Linux/gcc but crashes on latest AIX v10.1 compiler
#include <fstream>
#include <assert.h>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/string.hpp> // no need to include <string>
#include <boost/serialization/export.hpp> // explicit code for exports (place last)
class RepeatBase {
public:
RepeatBase() {}
virtual ~RepeatBase() {}
virtual const std::string& name() const = 0;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {}
};
class RepeatDerived : public RepeatBase {
public:
RepeatDerived( const std::string& name) : name_(name) {}
RepeatDerived() {}
virtual const std::string& name() const { return name_;}
private:
std::string name_;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
// save/load base class information
ar & boost::serialization::base_object<RepeatBase>(*this);
ar & name_;
}
};
class Defs {
public:
Defs(const std::string& f) : fileName_(f), repeat_(new RepeatDerived(f)) {}
Defs() : repeat_(NULL) {}
~Defs() { delete repeat_;}
bool operator==(const Defs& rhs) const { return fileName_ == rhs.fileName_;}
const std::string& fileName() const { return fileName_;}
private:
std::string fileName_;
RepeatBase* repeat_;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int /*version*/) {
ar & fileName_;
ar & repeat_;
}
};
BOOST_CLASS_EXPORT(RepeatBase);
BOOST_CLASS_EXPORT(RepeatDerived);
BOOST_SERIALIZATION_ASSUME_ABSTRACT(RepeatBase)
int main()
{
// With this explicit cast we get a bit further, but still crashes on AIX
// i.e crash on ar.save_pointer(vp, bpos);
//
// boost::serialization::void_cast_register<RepeatDerived, RepeatBase>(0,0);
const Defs saveDefs("saveFile.txt");
{
// Save the defs file
std::ofstream ofs( saveDefs.fileName().c_str() );
boost::archive::text_oarchive oa( ofs );
oa << saveDefs;
}
{
// Restore the defs file
Defs loadDefs;
std::ifstream ifs(saveDefs.fileName().c_str());
boost::archive::text_iarchive ia(ifs);
ia >> loadDefs;
assert( saveDefs == loadDefs );
}
return 0;
}
//=========================================================================================
This bug was present in boost 1.39 and is still broken in boost 1.40.
The code above shows that base/derived relationship work on one compiler
but is _competely_ broken another. Explicitly registering the base/derived
relationship just moves the crash to a later point.
template<class T>
struct polymorphic
{
static void save(
Archive &ar,
T & t
){
......
// convert pointer to more derived type. if this is thrown
// it means that the base/derived relationship hasn't be registered
vp = serialization::void_downcast(
*true_type,
*this_type,
static_cast<const void *>(&t)
);
if(NULL == vp){
boost::serialization::throw_exception(
archive_exception(archive_exception::unregistered_cast) //< crash1 here
);
}
.....
ar.save_pointer(vp, bpos); //< crashe2 here after explicit base/derived registration
I thought this bug had been fixed, so I am not sure if this is a regression ?
Is there any way I can help, as this is show stopper bug for us.
Best regards,
Ta,
Avi