
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