0x26res
0x26res

Reputation: 13952

How does boost serialization actually save const object

Considering the following example of serialization, how does boost cope with saving data when this data is const and the serialization function is not a const function ?

Is there a const cast somewhere ?

  struct Settings
  {
    Settings();
    uint32_t    buffers_size;
    uint32_t    messages;
  };

  template < class Archive >
  void serialize(Archive& ar, Settings& settings, unsigned int /*version*/)
  {
    using boost::serialization::make_nvp;
    ar 
      & make_nvp< uint32_t >("buffers_size", settings.buffers_size )
      & make_nvp< uint32_t >("messages", settings.messages);
  }

Upvotes: 2

Views: 1310

Answers (1)

Luc Touraille
Luc Touraille

Reputation: 82171

As far as I can tell, the constness is indeed casted away before saving the object. I think the relevant code is in oserializer.hpp:

template<class Archive, class T>
BOOST_DLLEXPORT void oserializer<Archive, T>::save_object_data(
    basic_oarchive & ar,    
    const void *x
) const {
    // make sure call is routed through the highest interface that might
    // be specialized by the user.
    BOOST_STATIC_ASSERT(boost::is_const< T >::value == false);
    boost::serialization::serialize_adl(
        boost::serialization::smart_cast_reference<Archive &>(ar),
        * static_cast<T *>(const_cast<void *>(x)),
        version()
    );
}

Before this method is called, the serialized object reference is turned into a const void *, corresponding to the second parameter here. The constness of this pointer is casted away, and the resulting pointer is casted to the appropriate pointer type, which is then dereferenced.

This raises the question of the possibility of invoking undefined behavior when trying to serialize a const object: if the serialize member/free function somehow modifies the object, then creating a const object and saving it to an archive would be undefined behavior, and go unnoticed at compile-time!

If you split the function into save and load, then you must mark save as const, which prevents you from accidentally modifying the object.

Upvotes: 2

Related Questions