On 10/18/15 12:47 AM, John Maddock wrote:
I think this is the correct way to do things (and is what my patch does, but I'm fine if you revert to the old way).
I've included the original stream_buffer_saver. I had originally taken it out to simplify things to track down the original issue. So things should be fine now. I've tested it on my machine which includes gcc and clang and also tested on C++03 and C++11. I've also got my bjam settings so that I think any visibility failures should be detectible on my system. I've uploaded these changes to develop and hopefully thing should start looking good. We'll see.
If you do any other thing then you introduce facet-lifetime issues as the archive is destroyed before the iostream leaving the iostream's locale with a dangling pointer (even making the facet lifetime global in the serialization lib doesn't work, because if someone writes an archive to cout, then the serialization lib is unloaded before the std lib and cout is left with a dangling pointer again).
I get this - that is the point of the stream_buffer_saver. When it's destroyed, it puts the streambuffer back into it's orginal state. Things were made more complicated by the standard codecvt idiom of allocating with new and letting the stream buffer manage the lifetime. Also it's very hard to figure out the design and motivation of the standard library's usage of facets etc. Also, it seems I'm not the only one with this problem. I don't have confidence that all the standard library implementations have this exactly right.
Let me know if you have a test case you want me to try and debug,
The original test case which set me on this path is contained in the test_z test which is what I use to hold the current test case I'm working on. FWIW - my procedure is: a) select a trac item which looks the simplest from the list and has a reasonable test case. b) copy the test case into the test_z source code. c) make sure it fails on my machine d) often I discover that the user has made some mistake, In this case I'll inform the user on the trac item - which keeps a whole thread of dialog between myself and complainer. Usually I'm right then I can just be done. Sometimes I might tweak the documentation in the hope of not getting another similar bogus complaint e) If it's legitimate, I'll debug it and make a change f) about half the time, this has an unintended and maybe obscure side effect which turns the process into a much bigger operation than anticipated. g) I check in the changes into develop and usually find that I've broken something in some environment I don't have. So the loop continues. h) By this time, I want to give up and just role things back and live with the bug. But I can't do that because I've already invested too much to just do that. I know that this is sort of irrational as it's a "sunk cost". But I always convince myself that "I'm almost there - just one more iteration". i) finally it's done and everything works everywhere. j) so I check into master. k) then the cycle continues a little longer. l) things stop happening and then I guess it's done. I only relate the above for those interested in what it means to be a boost library maintainer. It means you've got a borderline personality disorder which you attempt to address by indulging it. Guess it works for me. So I do appreciate your help and participation in cases such as this. Robert Ramey