Boost logo

Boost :

Subject: Re: [boost] [Serialization] Bizarre bug
From: Robert Ramey (ramey_at_[hidden])
Date: 2009-08-08 13:01:46


Jarl Lindrud wrote:
> Robert Ramey <ramey <at> rrsd.com> writes:
>
>>
>> Jarl Lindrud wrote:
>>> Robert Ramey <ramey <at> rrsd.com> writes:
>>> Hmmm. This implies that the meaning of the code "ar << t" , depends
>>> on the content of the entire program.
>>
>> I would agree that the implementation of ar << t depends upon the
>> content of the entire program.
>>
>
> But it is actually meaning, not implementation... Depending on the
> contents of the entire program, the archives will have one binary
> format or another, and will either be readable by other pre-existing
> programs, or not. That's really part of the specification of "ar <<
> t" , not the implementation.

The specification of the semantics of ar << t supports either
interpretation.
The actual semantic is dependent on the selected implemenation level
and tracking behavior.

>> Default tracking is "track_selectively" and default implementation
>> level is "? - include class information in the archive. You might
>> want to change the implementation level for your classes to
>> "track_always".
>>
>
> But perhaps I do want tracking turned on, in certain situations, and
> turned off in other situations. What's important is that I know for
> sure, for any given serialization operation, what the tracking
> setting actually is, and that it doesn't change implicitly later on,
> when somebody adds seemingly innocent code to the program.

LOL - then just do that! That is, set the implementation level
and tracking behavior for each of your classes. That way
they would never change - until you change the class definitions
in which case you've go class versioning to help you out.
This is supported by the library.

>> Actually, I see a lot of merit in this argument. In fact the whole
>> concept of "serialization_traits" is amounts to a global table
>> keyed on data type. So it does have the same problem - ie side
>> effects that any global table does. It's not as bad a normal
>> because it doesn't change dynamically but it can still be a
>> problem. On the other hand, having to explicitly specify
>> these traits for each invocation of ar << ? and ar >> ?
>> would be very tedious and I dare say unpopular. And likely
>> prone to other kinds of errors.
>
> <somewhat OT>
>
> It could be made simpler than that - the traits would have a default
> compile- time setting, and then users could override those settings
> through a runtime call. They would presumably do that at program
> startup (if at all), and then they would still have the option of
> adjusting the traits again, for any particular serialization
> operation, if and when its needed.

If you want to do it a startup - you might as well do it a compile
time by setting your own traits - see above. if you want to override
it for a particular operation - you can make a serialization wrapper.
(Currently this can't be done for all traits - this has been noted,
but it has never been addressed due to lack of interest)

> If they want the default compile-time traits, they wouldn't have to
> do anything.

"They" don't.

> I do think the whole traits issue needs to be dealt with at runtime.
> What if I need to read archives produced by another program, which in
> an older release had tracking disabled, and then in a later release
> had it enabled. If the tracking trait is set at compile-time then I
> will only be able to read one or the other.

I think you need to study the current library some more. The default
implementation level for user classes is to store class version, and
tracking behavior in the archve. When the archive is read, the
tracking which was set when the archive was created is that which
is used when the archive is read. The "current" tracking setting
is only used if the class information wasn't stored in the archive.

For some commonly used types - in this case vector<char> it
was decided that the version would "never change" and that
efficiency considerations argued for using "track_selectively"
so the default traits were set accordingly. Of course one can
differ on what the default should be in any particular case -
but that's a different topic.

To summarize, I don't see what's missing in order to do what
you want. Don't like my selection of default traits settings
- don't use them. Don't like the concept of "side effects" -
just explicitly assign the traits you want to use for each
of your classes. Want to tweak them for each invocation
of the << or >> operator, make a wrapper. I don't see that
the library inhibits you from doing what you want.

> </somewhat OT>
>
> But getting back to the original problem - really the most important
> thing here is that the default tracking level should be unaffected by
> compile-time instantiation. As long as I know what the default is,
> and that it won't change under my feet, then I would be OK with that.
>
> Would that be feasible to implement?

Just specify your own setting with BOOST_CLASS_TRACKING(mytype,
track_always)
or BOOST_CLASS_TRACKING(mytype, track_never) for your own
classes.

If this is too much - then you could tweak the "tracking.hpp" file
so that the default is "track_always" or "track_never" or whatever.

> Anyway, thanks Robert for bearing with me... I know you get a lot of
> requests from a lot of people.

Actually, it's very odd to me that I get so few requests and questions.
The perception is that the library is widely used. But, if that's the case
I'm very surprised how little traffic I get. And 80 percent of the
questions
are just people who don't want to read the manual.

Robert Ramey


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk