
Robert Ramey wrote:
Peter Dimov wrote:
Robert Ramey wrote:
Peter Dimov wrote:
So I would amplify my statement above that I can't understand why someone would use the above on an type that might track the address.
For several reasons, the most important one being that tracking is on by default.
Thats why I like the trapping behavior. It will indicate that the default - track_selectively - is probably not appropriate for this case.
BTW - I thought a little more about your example:
#include <fstream> #include <boost/archive/text_oarchive.hpp> #include <boost/static_assert.hpp> class X { }; X construct_X_from(int i); int main(){ std::ofstream os("file"); boost::archive::text_oarchive oa(os); int i; // the following traps with vc 7.1 // fails to compile with gcc 3.3 and borland // compiles - doesn't trap with comeau - I believe that it traps // but BOOST_STATIC_ASSERT doesn't work for comeau in this case oa << construct_X_from(i); }
sure enough, it fails to compile on at least a couple of compilers. Apparently those compilers don't like taking a reference to something on the argument stack. So with these compilers the whole issue of the trap never presents itself. This behavior seems correct to me.
Right, that's because your operator<< takes a non-const reference. So the code above is not prevented by your STATIC_ASSERT trap, but it's still not supported by the library. Change the function to return "X const", as a user might do when faced with the error, and it will compile, not trap, and probably not do what one wants. (The other workaround would be to use a named variable and save that. This case will be trapped if the variable is not const.)
I'm not sure why the others compile it.
For backward compatibility; many years ago non-const references to temporaries were allowed.
But more fundamentally, address tracking is not a property of the type.
Maybe - maybe not. I would say that's a topic for another time.
[...]
LOL - I'm sure that marking every usage of << as to whether it should be tracked or not would be very popular. In fact the default is almost always what on wants. The trap is to highlight likely cases where it may not be.
[...]
again - generaly the defaults are what most people would want. No one has raised any issue regarding the defaults until now.
I think that the default behavior on a sequence of two saves with the same address should be to write the two objects, as if address tracking isn't on. If later a pointer to that address is saved, an exception should occur. Or more generally,
- one value save, then N pointer saves sharing the same address should be OK;
- M pointer saves sharing the same address should be OK; (*)
- K value saves sharing the same address should be OK and result in K copies in the archive;
Currently you'll only get one copy for this case unless you suppress tracking.
- all other sequences raise an exception at first opportunity.
Is there any reasonable use case which is prohibited by the above rules?
(*) This promotes questionable coding practices but is consistent with the current behavior. :-)
Accept as noted above, that's how it works now.
The question isn't really the defaults. But whether my attempts to trap likely cases where they should be overriden are mis-guided.
You keep dismissing everything I say. It's a topic for another time; it's not about the defaults. It is. The _only_ reason that you had to trap some cases is because your defaults don't work for them! If you change the default behavior to handle these cases, while still allowing previous uses to work as they did, you will no longer need to trap anything. Which is why I proposed one possible default behavior that seems to fit that description, and asked you whether it sounds reasonable.