
Vladimir Prus wrote:
This behaviour will make the case that the current assertion is meant to catch just work.
I believe a) that it currently works exactly as Peter thinks it should b) that problems still can and will occur c) that the trap is useful in detecting a significant and worthwhile portion of those problems d) at a small cost in convenience. To illustrate my case, lets take peter's interesting example. class construct_from { ... }; void main(){ ... Y y; ar << construct_from(y); } I never considered this specific example and I would consider uncommon but it is a legitimate and plausable usage of the library. First lets assume that the trap is commented out. 1) as written above, it fails to compile on a conforming compler. This is because the << operator takes a reference as its argument. So we make a slight change to make it pass. void main(){ ... Y y; construct_from x(y); ar << x; } 2) this compiles and executes fine. No tracking is done because construct_from has never been serialized through a pointer. Now some time later, the next programmer(2) comes along and makes an enhancement. He wants the archive to be sort of a log. void main(){ ... Y y; construct_from x(y); ar << x; ... x.f(); // change x in some way ... ar << x } Again no problem. He gets to copies in the archive, each one is different. That is he gets exactly what he expects and is naturally delighted. 3) Now sometime later, a third programmer(3) sees construct_from and says - oh cool, just what I need. He writes a function in a totally disjoint module. (The project is so big, he doesn't even realize the existence of the original usage) and writes something like: class K { shared_ptr<construct_from> z; template<class Archive> void serialize(Archive & ar, const unsigned version){ ar << z; } }; He builds and runs the program and tests his functionality and it works great and he's delighted. 4) Things continue smoothly as before and a month goes by before its discovered that when loading the archives made in thelast month (reading the log). Things don't work. The second log entry is always the same as the first. After a very long and acrimonius email exchanges, its discovered that programmer (3) accidently broke programmer(2)'s code because by serializing via a pointer, the behavior in an unrelate piece of code is changed. Bad enough, but worse yet the data wasn't being saved and cannot not be recovered. People are really upset and disappointed with boost (at least the serialization system). Now suppose the trap is turned on. How are things different? 1) Right away, the program traps at ar << x; The programmer curses (another %^&*&*( hoop to jump through). If he's in a hurry (and who isn't) and would prefer not to const_cast - because it looks bad, He'll just make the following change an move on. const construct_from x(y); ar << x; Things work fine and he moves on. 2) Now programer 2 wants to make his change - and again (^&%*^%) another annoy const issue; const construct_from x(y); ar << x; ... x.f(); // change x in some way ; compile error f() is not const ... ar << x He mildly annoyed now he tries the following: a) He considers making f() a const - but presumable that shifts the const error to somewhere else. And his doesn't want to fiddle with "his" code to work around a quirk in the serializaition system b) He removes the "const" from "const construct_from above - damn now he gets the trap. If he looks at the comment code where the BOOST_STATIC_ASSERT occurs, he'll do one of to things i) This is just B.S. Its making my life needlessly difficult and flagging code that is just fine. So I'll fix this with a const cast and fire off a complaint to the list and mabe they will fix it. ii)Oh, this trap is suggesting that the default serialization isn't really what I want. Of course in this particular program it doesn't matter. But then the code in the trap can't really evaluate code in other modules (which might not even be written yet). OK, I'll at the following to my construct_from.hpp to solve the problem. BOOST_SERIALIZATION_TRACKING(construct_from, track_never) Program compiles with no casts and no traps and executes just as expected (as above) 3) Now programmer (3) comes along and make his change. The behavior of the original (and distant module) remains unchanged because the construct_from trait has been set to track_never so we always get copies and the log is always what we expect. His program also works as expected even thought it saves/loads multipe copies. //Alert: Ironic humor follows On the other hand, Now he gets another trap - trying to save an object of a class marked "track_never" through a pointer. So he goes back to construct_from.hpp and comments out the BOOST_SERIALIZATION_TRACKING that was inserted Now the second trap is avoided, But damn - the first trap is popping up again. After much acrimonious email the situation is resolved so to no one's real satisfcation. // End humor alert This second trap doesn't currently exist. But as I writing the above made me think about it, I now believe it should also be implemented. So contrary to my original intent - the above isn't funny after all - its serious. Now (without the second trap) what is going happen is the following. 4) Actually programmer (3) changes are not going t function as shared_ptr<construct_from> is not have a single raw pointer shared amonst the instances but rather multiple ones. Things won't work. Of course this won't be obvious until a month from now and we're back in the same boat. This is my best attempt to illustrate why the trap (now traps?) are important. Not perfect but better than nothing. Vladimir started this thread with the question of whether the inconvenience created by the traps was a worthwhile trade off for any benefit. I agree that this is the fundamental question and have done my best to address it here. I believe that this scenario illustrate at least one case where it would. The inconvenience is small an and actually leads to a more correct program. Note that I didn't contrive this example, its Peter's example - I just took it to its logical conclusions. Robert Ramey