Boost logo

Boost :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2005-06-24 02:33:15


Robert Ramey wrote:

>>Each check is only reasonable if it finds more bugs than it causes
>>problems. We seem to disagree about the proportion for the *specific case*
> of the >check in serialization library.
>
> I guess so. But you might check Joaquin's previous message regarding this.

I can't find any messages from Joaquin in this thread? Maybe you can send a
link or forward that message to me?

>>I'm not sure this behaviour is right. It certainly matters if I save
>>the
>>*same* object as pointer or not. Why does it matter if I have *another*
>>object by pointer.
>
>>Suppose you've saving an object with the same address twice. There
>>possible situations are:
>
>>1. Both saves are via pointers. You enable tracking for this address;
>>only one object is actually saved. User is responsible for making sure
>>that the object does not change between saves.
>
>>2. First save is via pointer, the second is not by pointer. You throw
>>pointer_conflict.
>
>>3. First save is not by pointer, second is by pointer. You ehable
>>tracking >for this address.
>
>>4. Both saves are not via pointer. You don't track anything.
>
>>Is there anything wrong with above behaviour?
>
> #3 -for this address-. We can't know at compile time what the addresses of
> the objects are. If an object of a certain type is serialized anywhere in
> the program through a pointer, we have to instantiate code to track
> pointers.

Sure, you have to *instantiate code*. But you can decide at runtime if each
specific address needs tracking.

>>> class a (
>>> X & m_x;
>>> ....
>>> };
>
>>And how would you deserialize this, given that references are not
> rebindable?
>
> Specialization of save/load_construct_data

If the user is required to provide special hooks here, he might as well take
special care when saving reference, no? In "save_construct_data"?

>> >>> for(...{
>>> >>> X x = *it; // create a copy of
>>> >>> ar << x
>>> >>> }
>>> How do we know that one of the x's saved in the loop is not
>>> serialized asa pointer somewhere else?
>
>>You keep a set of addresses of all saved objects.
>
> Isn't it just easier and better just to let the serialization system do it
> by reformulating the above as:
>
> For(...
> const X & x = *it;
> ar << x
> }

1. To clarify "you keep a set.." above means "serialization library keeps".

2. If serialization library can keep the set of saved objects, then wouldn't
it be easier if serialization worked in both cases?

3. I'm getting dizzy. Does 'const' has any other effect that disable your
STATIC_ASSERT? If yes, then it does not make it easier to figure out of
"one of the x's saved in the loop is serialized as a pointer somewhere
else".

Inside:

   X x = *it;
   ar << x;

you record address of 'x' and offset in archive where it's saved (or some
other id). When user later does:

   X* x = whatever;
   ar << x;

you check you set of addresses. If the address if found, you write a
reference to previous object to the archive. Looks pretty simple to me.

>>> We have to track ALL x's because we don't know which ones if any are
>>> being tracked somewhere else. It could even be in a different module.
>
>>Right, you need to track all addressed while saving, but in archive the
>>saves from the above loop need not be marked as tracked.
>
> Currently there is no way (and no need in my opinion) to assign tracking
> behavior for each invocation of the << and >> operator. If you want to
> suppress tracking altogether for type X you can assign track_never trait.
> In the case the STATIC_ASSERT won't trap - so there you are.

Returning to example you gave in the first email in this thread:

>
> Its very easy to write
> for(...{
> X x = *it; // create a copy of
> ar << x
> }
>
> all the x's are at the same address so if they happen to be tracked
> because
> a pointer to some X in serialized somewhere in the program, then the
> subsequent copies would be supprsed by tracking.

What does "the subsequence copies would be supressed by tracking"? Are you
saing that only one 'X' will be stored in archive? And what will happen
duing deserialization. Will you load just one 'X' object, and then for each
iteration of deserialization loop, make a copy of it?

Then it's very strange behaviour, and what's even more worring, that
behaviour is activated if some *unrelated* object of the same time is saved
in some other module that I have no idea about. That's very fragile.

Or do you expected that every given type 'X' is either serialized by value,
or by pointer, but never by both ways? That sounds like a artificial
restriction.

- Volodya


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