Hi there, I was just toying around with the boost serialization lib.
Unfortunately I have a problem with serializing a map. Here is what I
did:
#include <map>
#include <string>
#include <iostream>
#include <algorithm>
#include <fstream>
#include
This is explainined in the section - "rationale" in the documentation. The following changes would make it work; Christian Henning wrote:
Hi there, I was just toying around with the boost serialization lib. Unfortunately I have a problem with serializing a map. Here is what I did:
#include <map> #include <string> #include <iostream> #include <algorithm> #include <fstream>
#include
#include #include using namespace std;
struct Settings { int Brightness; int Contrast; };
// Table indexed by strings typedef pair< string, string > Key; typedef map< Key, Settings* > Table;
int _tmain(int argc, _TCHAR* argv[]) { Table aTable;
aTable[ make_pair("Mueller","Meier") ] = new Settings(); aTable[ make_pair("Meier","Mueller") ] = new Settings(); aTable[ make_pair("Meier","Meier") ] = new Settings();
Settings* pSettings = aTable[ make_pair("Mueller","Meier") ]; pSettings->Brightness = 99; pSettings->Contrast = 8;
{ const Table & stable = aTable;
ofstream ofs( "Settings.txt" ); boost::archive::text_oarchive oa( ofs ); oa << sTable; }
return 0; }
Robert Ramey
Thanks Robert, that was it! I haven't made it to the Rational section,
so far. But I will, promised. ;-))
This probably has been discussed a million times, already. But, is it
possible to change the line 36 in collections_save_imp.hpp from
unsigned int count = s.size();
to
size_t count = s.size();
My compiler, VC 7.1 is going crazy and spits out a warning of 100 lines !!!
Thanks,
Christian
On 5/24/06, Robert Ramey
This is explainined in the section - "rationale" in the documentation. The following changes would make it work;
Christian Henning wrote:
Hi there, I was just toying around with the boost serialization lib. Unfortunately I have a problem with serializing a map. Here is what I did:
#include <map> #include <string> #include <iostream> #include <algorithm> #include <fstream>
#include
#include #include using namespace std;
struct Settings { int Brightness; int Contrast; };
// Table indexed by strings typedef pair< string, string > Key; typedef map< Key, Settings* > Table;
int _tmain(int argc, _TCHAR* argv[]) { Table aTable;
aTable[ make_pair("Mueller","Meier") ] = new Settings(); aTable[ make_pair("Meier","Mueller") ] = new Settings(); aTable[ make_pair("Meier","Meier") ] = new Settings();
Settings* pSettings = aTable[ make_pair("Mueller","Meier") ]; pSettings->Brightness = 99; pSettings->Contrast = 8;
{ const Table & stable = aTable;
ofstream ofs( "Settings.txt" ); boost::archive::text_oarchive oa( ofs ); oa << sTable; }
return 0; }
Robert Ramey
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Christian Henning wrote:
Thanks Robert, that was it! I haven't made it to the Rational section, so far. But I will, promised. ;-))
This probably has been discussed a million times, already. But, is it possible to change the line 36 in collections_save_imp.hpp from
unsigned int count = s.size();
to
size_t count = s.size();
My compiler, VC 7.1 is going crazy and spits out a warning of 100 lines !!!
Well, IMO is must be done. It seems like bug, though not a serious one. -Thorsten
This is being changed in the course of some adjustments to support fast serialization of arrays. Its currently in the HEAD and should eventually find itself into release -1.35 I would expect. Robert Ramey Thorsten Ottosen wrote:
Christian Henning wrote:
Thanks Robert, that was it! I haven't made it to the Rational section, so far. But I will, promised. ;-))
This probably has been discussed a million times, already. But, is it possible to change the line 36 in collections_save_imp.hpp from
unsigned int count = s.size();
to
size_t count = s.size();
My compiler, VC 7.1 is going crazy and spits out a warning of 100 lines !!!
Well, IMO is must be done. It seems like bug, though not a serious one.
-Thorsten
Robert Ramey wrote:
This is explainined in the section - "rationale" in the documentation. The following changes would make it work;
int _tmain(int argc, _TCHAR* argv[]) { Table aTable;
{ const Table & stable = aTable;
ofstream ofs( "Settings.txt" ); boost::archive::text_oarchive oa( ofs ); oa << sTable;
Robert, This issues seems to pop up again and again. It's just *so* surprising (nobody reads through all the docs of a library when they start to use it). As you remember, I had to contact you personally to help me with Pointer Container Serialization --- it was not because I hadn't tried before contacting you (I spent hours trying to figure out what was wrong). (I have documented a seperate todo-list for people using Boost.Pointer Container and serialization just to remember them of this isssue!). There has to be a better way. I read through your scenario again: http://www.boost.org/libs/serialization/doc/rationale.html#trap and I don't get very much of it. I understand the need for ensuring 1. no invalid archives are created. 2. no data is lost. 3. no runtime errors occur. but there has to be a better way, even if it means 3 becomes a runtime exception. Somehow the information of a class and how it is serialized must be localized ***in one place only*** so one programmer can't ruin the archieve of another programmer without his knowlegde. If this means 1. that by default, you can't serialize a pointer (you must ask for it), or 2. that by default, you have to define BOOST_SERIALIZATION_TRACKING that's ok. But something has to be done. -Thorsten BTW: I'm ok with T * t; ar >> t; failing (just make it part of the toturial). That's completely different from reading from an object.
Thorsten Ottosen wrote:
This issues seems to pop up again and again.
It's true that from time to time this question comes up. Though not very often it seems to me. On the other hand, since I've put this in I havn't had anyone complain that they've invalid archives (well maybe a couple of times due to bugs in in serialization code - but that's different.) which was a big pain in the rear to try to explain before.
It's just *so* surprising (nobody reads through all the docs of a library when they start to use it).
As you remember, I had to contact you personally to help me with Pointer Container Serialization --- it was not because I hadn't tried before contacting you (I spent hours trying to figure out what was wrong). (I have documented a seperate todo-list for people using Boost.Pointer Container and serialization just to remember them of this isssue!).
There has to be a better way. I read through your scenario again:
http://www.boost.org/libs/serialization/doc/rationale.html#trap
and I don't get very much of it.
I understand the need for ensuring
1. no invalid archives are created. 2. no data is lost. 3. no runtime errors occur.
but there has to be a better way, even if it means 3 becomes a runtime exception.
Hmmm - to ensure 2) that would have to occur on archive save - I'm not even sure that's possible. Even so it lot harder to track down than the current setup.
Somehow the information of a class and how it is serialized must be localized ***in one place only*** so one programmer can't ruin the archieve of another programmer without his knowlegde.
In my view all that should be in the header module which declares the class. This is always possible and that's what I always do. It's always grouped together in one place in one module. Personally I don't understand why everyone doesn't do it that way. Maybe we need a macro which specifes all the serialization traits for a type like BOOST_CLASS_TRAITS(tracking, abstract, etc...) rather than just letting people sprinkle them will-nilly all over their code.
If this means
1. that by default, you can't serialize a pointer (you must ask for it), 2. that by default, you have to define BOOST_SERIALIZATION_TRACKING
BTW: I'm ok with
T * t; ar >> t;
failing (just make it part of the toturial). That's completely
different from reading from an object.
Hmm - I'm doubtful that would be a popular idea. But, you want to establish a different default policy for your own company, you could easily tweak tracking.hpp so that the default would be track_never, - but then you'll get a trap when you try to serialize a pointer - which I guess would be what you want. We've had some experience with this and from my standpoint its been positive. This was discussed at length and I've conceded that knowledgable people can disagree on this point. So I do have a couple of ideas which mollify those who disagree on this point. a) I could change the BOOST_STATIC_ASSERT to BOOST_STATIC_WARNING This would emit an warning message on most compilers. Then people are free to ignore it. Of course from one standpoint its worse, some people will complain about the warning then ignore it and then complain again about creating an unreadable archive - LOL. So I'll have the worst of both worlds. b) We could make the emmision of the message (assert or warning) conditional or suppressable via definition of something like BOOST_SUPPRESS_WARNINGS (which could be part of BOOST_STATIC_WARNING). The argument that people don't/won't read the documentation doesn't evoke much sympathy from me. On one hand we want to permit someone to make an egregious error so that he won't have to read the manual to understand the nature of his error. I don't buy it. In the code where the static assertion occurs there is a pointer to the explanation in the manual. It bother's me much less to have someone complain about this error than it does getting email titled "bug in serialization" from people "too busy" to read the portion of the manul pointed to by the comment in the line where the error message is emitted. I want everyone to be successful using the library - even if they complain that it requires them to write good code. Robert Ramey
Robert Ramey wrote:
Thorsten Ottosen wrote:
b) We could make the emmision of the message (assert or warning) conditional or suppressable via definition of something like BOOST_SUPPRESS_WARNINGS (which could be part of BOOST_STATIC_WARNING).
The argument that people don't/won't read the documentation doesn't evoke much sympathy from me. On one hand we want to permit someone to make an egregious error so that he won't have to read the manual to understand the nature of his error. I don't buy it. In the code where the static assertion occurs there is a pointer to the explanation in the manual. It bother's me much less to have someone complain about this error than it does getting email titled "bug in serialization" from people "too busy" to read the portion of the manul pointed to by the comment in the line where the error message is emitted.
I want everyone to be successful using the library - even if they complain that it requires them to write good code. ^^^^^^^^^ IMO the current policy of the library actually forces me to write bad/ugly code because if I ever want to serialize something in a non-const context I have to force it to const artificially.
This will be short because I know we've been over this point endlessly in the past, but I'll try one more time. Make a macro to control this behavior: BOOST_SERIALIZATION_CONST_STRICT or whatever. Make this optional. When someone posts an issue with an archive, tell them to recompile with this option turned on so that they can help find the problem. Then the rest of us can write normal code and the library will behave as expected. Less people will need to read the fine print of the library. BTW, I suspect the decrease in bug reports might be a result of less folks being able to get "hello serialization" to compile and subsequently giving up on the library instead of the 'better' code that this 'enforces'. Jeff
Jeff Garland wrote:
Robert Ramey wrote:
I want everyone to be successful using the library - even if they complain that it requires them to write good code.
^^^^^^^^^ IMO the current policy of the library actually forces me to write bad/ugly code because if I ever want to serialize something in a non-const context I have to force it to const artificially.
This will be short because I know we've been over this point endlessly in the past, but I'll try one more time. Make a macro to control this behavior:
BOOST_SERIALIZATION_CONST_STRICT
or whatever. Make this optional. When someone posts an issue with an archive, tell them to recompile with this option turned on so that they can help find the problem. Then the rest of us can write normal code and the library will behave as expected. Less people will need to read the fine print of the library.
This is a grand idea.
BTW, I suspect the decrease in bug reports might be a result of less folks being able to get "hello serialization" to compile and subsequently giving up on the library instead of the 'better' code that this 'enforces'.
Right. We want people to use the library, not scare them off. -Thorsten
Robert Ramey wrote:
Thorsten Ottosen wrote:
I understand the need for ensuring
1. no invalid archives are created. 2. no data is lost. 3. no runtime errors occur.
but there has to be a better way, even if it means 3 becomes a runtime exception.
Hmmm - to ensure 2) that would have to occur on archive save - I'm not even sure that's possible. Even so it lot harder to track down than the current setup.
These three bullets are taken from your documentation of what teh benefits of your current setup is. I just don't get why serializing a non-const object can lead to them.
Somehow the information of a class and how it is serialized must be localized ***in one place only*** so one programmer can't ruin the archieve of another programmer without his knowlegde.
In my view all that should be in the header module which declares the class. This is always possible and that's what I always do. It's always grouped together in one place in one module. Personally I don't understand why everyone doesn't do it that way. Maybe we need a macro which specifes all the serialization traits for a type like BOOST_CLASS_TRAITS(tracking, abstract, etc...) rather than just letting people sprinkle them will-nilly all over their code.
Write a section in your tutorial called "Serialization best practices". If all that is needed is to always put serialization "derectives" together with the class declaration, that's a pretty cheap fix.
BTW: I'm ok with
T * t; ar >> t;
failing (just make it part of the toturial). That's completely
different from reading from an object.
Hmm - I'm doubtful that would be a popular idea.
Your docs state that this will fail when tracking has been set to something!
But, you want to establish a different default policy for your own company,
no, I don't want to do that. I want people to use your library and not turn it down because they can't get hello world to work.
The argument that people don't/won't read the documentation doesn't evoke much sympathy from me.
Well, people read documentation, but there is a limit to how much new stuff a programmers brain can taker per day. Not many read it all and remember it all.
On one hand we want to permit someone to make an egregious error so that he won't have to read the manual to understand the nature of his error. I don't buy it. In the code where the static assertion occurs there is a pointer to the explanation in the manual.
I certainly couldn't find that. Otherwise I wouldn't have asked you personally.
I want everyone to be successful using the library - even if they complain that it requires them to write good code.
If good code means "put serialization meta information with the class declaration", I agree. If you mean a << add_const( obj ); I don't agree. -Thorsten
participants (4)
-
Christian Henning
-
Jeff Garland
-
Robert Ramey
-
Thorsten Ottosen