Re: [Boost-users] Serialization newbie needs help
"Robert Ramey"
goes away. Any chance this could be added to a boost::serialization FAQ?
you mean change the section named "rationale" to "FAQ"?
Ermm... Yes, I suppose so. There ought to be some section that a newbie who is having problems would immediately look to see if this is a common problem. In my browser, the "Rationale" section of the documentation appears unexpanded by default. And even when I expand it, "Compile time trap when saving a non-const value" doesn't seem (when skimming the docs) relevant to the static assertion error. It also didn't appear in my Google search for the cryptic error message that the compiler produced.
The "Compile time trap" section of the documentation doesn't actually explain what "object tracking" is all about. Neither (amusingly) does the Boost->Serialization->Reference->Special Considerations->Object Tracking section!
Hmmm - well it's intended to. Maybe I just thought the meaning of the term "Object Tracking" obvious.
As a newbie, I can tell you that it wasn't obvious to me! :-) As I said, I wouldn't have expected the serialization library to do any automagical pointer stuff, so from this perspective, it's very hard to see what object tracking is, and why it would be necessary.
What on earth does it actually mean to serialize a pointer?
Exactly what you think it means - see above.
Well, once you've got an idea in your head about what should happen when a pointer is serialized (and had that concept for years, and written a whole library to implement it!), it probably seems obvious and "natural" that it should work that way. But to a newbie (to boost::serialization, not to C++), this behavior is rather surprising. For example if I do: my_class mc; my_class* mc_ptr = &mc; cout << mc_ptr; I don't get the my_class object sent to stdout. I get the value of the pointer itself. If I wanted the actual object displayed, I would dereference the pointer. So my intuition would be that boost::serialization would work in a similar way: if I wanted the object itself output/input, I would do it explicitly. I'm not trying to say that your approach is wrong. All I'm attempting to point out is that other people may have very different (and quite reasonable) expectations about what should happen.
And why would I want to do such a thing, anyway?
I don't know what your application is.
Sorry. What I meant was "Why would someone want this?" or "Why is this a useful feature?" Fundamentally, there are two approaches to dealing with pointer serialization: (1) disallow it altogether; or (2) serialize the pointed-to object, and do all the clever object-tracking stuff. The first approach has the benefit of simplicity . So the only reason to take the second approach would be if automagic pointer serialization is really useful. However, I can't think of an example of when this would be really useful. Hence my question. But if you could provide me an example of when pointer serialization shines, then I would say "Aha! Now I understand why Robert went to so much trouble to make this work.", and I could be at peace with the world again! :-) BTW, I don't want to sound like I'm bashing your library, so let me end with a compliment. I think the symmetric design of serialize(), with the same function used for both input and output, is one of the prettiest idioms I've seen in years. -- Dominick
Dominick Layfield wrote:
"Robert Ramey"
wrote: goes away. Any chance this could be added to a boost::serialization FAQ?
you mean change the section named "rationale" to "FAQ"?
Ermm... Yes, I suppose so. There ought to be some section that a newbie who is having problems would immediately look to see if this is a common problem.
In my browser, the "Rationale" section of the documentation appears unexpanded by default. And even when I expand it, "Compile time trap when saving a non-const value" doesn't seem (when skimming the docs) relevant to the static assertion error. It also didn't appear in my Google search for the cryptic error message that the compiler produced.
Actually, I've considered reviewing all the email in this list and summarizing the results in a section "Hints and Troubleshooting Tips". I think this is useful and necessary and useful, but I just havent gotten around to it.
The "Compile time trap" section of the documentation doesn't actually explain what "object tracking" is all about. Neither (amusingly) does the Boost->Serialization->Reference->Special Considerations->Object Tracking section!
Hmmm - well it's intended to. Maybe I just thought the meaning of the term "Object Tracking" obvious.
As a newbie, I can tell you that it wasn't obvious to me! :-)
As I said, I wouldn't have expected the serialization library to do any automagical pointer stuff, so from this perspective, it's very hard to see what object tracking is, and why it would be necessary.
Other libraries do this as well - Microsoft MFC for example
Well, once you've got an idea in your head about what should happen when a pointer is serialized (and had that concept for years, and written a whole library to implement it!), it probably seems obvious and "natural" that it should work that way.
But to a newbie (to boost::serialization, not to C++), this behavior is rather surprising. For example if I do:
my_class mc; my_class* mc_ptr = &mc; cout << mc_ptr;
I don't get the my_class object sent to stdout. I get the value of the pointer itself. If I wanted the actual object displayed, I would dereference the pointer. So my intuition would be that boost::serialization would work in a similar way: if I wanted the object itself output/input, I would do it explicitly.
Well, that is a good point. I would think the best behavior would be for the above to trap - but it doesn't
I'm not trying to say that your approach is wrong. All I'm attempting to point out is that other people may have very different (and quite reasonable) expectations about what should happen.
I realise this. I've tried to be clear about what the library does but it's not always clear to everyone.
Sorry. What I meant was "Why would someone want this?" or "Why is this a useful feature?"
The central and fundamental idea of the serialization library is to replicate any arbitray set of C++ data structures in another time and or place. Key words are "replicate", "arbitrary", and "C++". It was/is my goal to make the system all encompassing. I don't ask what people are going to do with it, I just make sure that the above statement is true. Now, if one believes the implementing the above makes for a library that is too complicated or too inefficient, or too .... well, then maybe its not a good choice for your application. But if you want to know that it will replicate whatever you throw at it - its the system for you. By using it, you free yourself from having to compromise your app to beable to gain persistence. You have persistence regardless of independently of any other design decisions you make in your app. It decouples you app from this the whole question of saving/reloading the data. And you don't have to mess up your app with a lot of quirky code to do this. Just some standard boiler plate - which is easy to verify - for each class. You can even include data from libraries you didn't write yourself - because its non-intrusive. So that's was/is my motivation. I want the user of this library to feel that he doesn't have to think about it as its all done. Of course reality is one has to do a little bit more than the minimum. One has to consider issues of tracking, duplicates, DLLS, creating derived objects, etc. Its not that hard and in any case its way easier than just redoing all the work from scratch.
Fundamentally, there are two approaches to dealing with pointer serialization: (1) disallow it altogether; or (2) serialize the pointed-to object, and do all the clever object-tracking stuff.
The first approach has the benefit of simplicity . So the only reason to take the second approach would be if automagic pointer serialization is really useful.
I can't tell users what they should or shouldn't do.
However, I can't think of an example of when this would be really useful. Hence my question.
But if you could provide me an example of when pointer serialization shines, then I would say "Aha! Now I understand why Robert went to so much trouble to make this work.", and I could be at peace with the world again! :-)
LOL - I haven't had time to make any real apps lately.
BTW, I don't want to sound like I'm bashing your library, so let me end with a compliment. I think the symmetric design of serialize(), with the same function used for both input and output, is one of the prettiest idioms I've seen in years.
And that's the one thing I didn't do - I believe I "borrowed" it from Jens Maurer. One tiny point. I'm aware that the "const" trap is annoying. But I've become convinced that the annoyance is small compared to the hassles it saves me and users from. I suspect that those who have a problem with aren't in the habit of using "const" everywhere they can. Robert Ramey
-- Dominick
On Saturday, August 18, 2007 at 16:51:34 (-0600) Dominick Layfield writes:
...
Fundamentally, there are two approaches to dealing with pointer serialization: (1) disallow it altogether; or (2) serialize the pointed-to object, and do all the clever object-tracking stuff.
The first approach has the benefit of simplicity . So the only reason to take the second approach would be if automagic pointer serialization is really useful.
However, I can't think of an example of when this would be really useful. Hence my question.
I'm baffled how you can't see the utility of serializing pointers and thereby maintaining object relationships. Suppose you have a list of objects, and several other structures that map to this list and to other lists of objects. These relational structures may be very expensive to construct, and extremely large. Being able to write this: os & list & map1 & map; Instead of rebuilding the maps is very convenient. Were we not to have object tracking, it would have made my job serializing our massive and intertwined data structures much, much more difficult. Bill
At 06:51 PM 8/18/2007, Dominick Layfield wrote:
if you could provide me an example of when pointer serialization shines, then I would say "Aha! Now I understand why Robert went to so much trouble to make this work.", and I could be at peace with the world again! :-)
(Apologies if someone else has already said this more succinctly; I'm still catching up with list traffic from a recent vacation.) Suppose your application has classes A and B. Class A contains a B* pointer. It doesn't directly contain a B instance; it points to a distinct B instance. To me, the most compelling argument for object tracking is when you have two instances of A, a1 and a2, each of which points to the SAME B instance b1. a1 ---> b1 <--- a2 You serialize that data structure. When a subsequent run of the app reloads it, let's say that you now have A instance a3 pointing to B instance b3, and A instance a4 pointing to a distinct B instance b4. a3 ---> b3 a4 ---> b4 Is that acceptable? Probably not, else why would the original session have linked the data that way? Object tracking is the way the serialization library recognizes the shared B instance and reconstitutes two new A instances which, again, contain pointers to the SAME B instance. a3 ---> b3 <--- a4
participants (4)
-
Bill Lear
-
Dominick Layfield
-
Nat Goodspeed
-
Robert Ramey