0
101 Sep 09, 2005 at 18:17

Hello,

I have been using boost::serialization recently, and I am currently trying to get a better understanding of the design choices made in this library by experimenting with my own simplistic serializer.

And the first problem I am running into is const-correctness.

I am working on non-intrusive serialization, for I think this is the most conveninent. User code has to partially specialize a template like this:

template<class Archive, class Object> void serialize(Archive & a, Object & o) {
// ...
}

template<class Archive> void serialize(Archive & a, my_class & c) {
a & c.x;
a & c.y;
}


And the serialization mechanism will instanciate a version with load_archive and save_archive if needed. For saving, the operator & of the archive takes a const reference to an object, and the loading one takes non-const. But the problem is that the partial specialization cannot handle both const and non-const versions. And I don’t want to require the two specializations to be written by the “user”, because this is error-prone.

So for now, I am using const_cast to always send a volative reference to the serialize functions, but this doesn’t look very clean. The operators in the archive classes are const-correct, but nothing prevents “user code” from modifying the object…

From what I have seen, boost also casts to non-const, but I was wondering if there was some other way around.

3 Replies

0
101 Sep 09, 2005 at 18:23

One possibility is to keep a run-time flag in the Archive object as to whether it should be considered const. Set this flag at the point where you perform the cast to non-const. Check this flag in methods on the Archive object that can be called by the user code to modify the object.

0
101 Sep 09, 2005 at 18:38

Thanks for your answer, but this is not exactly the problem I am trying to address. The archive methods are const-correct, for example save_archive defines “template<class T> void operator & (const T &)” and load_archive defines “template<class T> void operator & (T &)”. My concern is that inside the template specialization I request the “user code” to implement, such thing can be written:

template<class Archive> void serialize(Archive & a, my_class & c) {
a & c.x;
a & c.y;
c.x = 123; // << here
}


If the code is currently saving an instance of my_class, since the const qualifier has been removed, this could lead to some memory violation.

0
101 Sep 09, 2005 at 23:16

If the user is writing code that will serve for both const and non-const objects, you will just have to give them non-const as you do at the minute. Warn extensively in the documentation that this proviso effects the code, and try and force the compiler to spit out errors when the user has done something violating const-correctness when saving.