Boost.Serialization: error checking
I am experimenting with Boost.Serialization. I tried to de-serialize a (binary) file written for a *different* class. Obviously, this can not work. However, there is not thrown an exception. Question: (How) can I determine that the reading failed? (In case of corrupted or non-matching archives.) (I have attached a small demo.) Best regards Christoph
I've encountered the same issue(s) in the past where signals will be
raised when the data serialized is nothing close to what is expected.
I have been able to deal with it is by doing one, or all, of the following:
Derive all types which are "Serializable" from common base, then
always try to unserialize to<->from that base. From there,
switch/vector on the derived type, either through RTTI or some other
mechanism.
I would also recommend overloading the sig_hdlr, so you can
gracefully shutdown in case something runs-a-muck.
Hope this helps,
-Tim
On 11/1/07, Christoph
I am experimenting with Boost.Serialization. I tried to de-serialize a (binary) file written for a *different* class. Obviously, this can not work.
However, there is not thrown an exception. Question: (How) can I determine that the reading failed? (In case of corrupted or non-matching archives.)
(I have attached a small demo.)
Best regards Christoph
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Regards, Timothy St. Clair [timothysc@gmail.com]
Personally I would not use this approach. To some extent
it can be seen as a matter of taste. I prefer to spend effort
in finding, fixing, and preventing the source of the problem.
So if there is an easy mistake to make which makes archives
which cannot be loaded, I would be interested in hearing
about it. I have considered making and "archive adaptor"
which would add redundent data to an archive to detect
save/load mismatches, editing of archive data outside
the serialization system and things like that. Also we
might add and "archive class" key to the header so
that an attempt to read the archive with the wrong
code would be detected. Of course, if this is a big
problem at your installation, it would be easy to add
a string at the start of each archive which specified
the class name of the archive creating it and
checks the class name of any archive being loaded.
Just some ideas for cases where it might be difficult
to guarentee that the loading archive class isn't
compatible with the saving archive class.
But I have to confess that I don't see this as a big problem.
And I don't think its something that the library can solve.
Robert Ramey
"Tim St. Clair"
I've encountered the same issue(s) in the past where signals will be raised when the data serialized is nothing close to what is expected.
I have been able to deal with it is by doing one, or all, of the following:
Derive all types which are "Serializable" from common base, then always try to unserialize to<->from that base. From there, switch/vector on the derived type, either through RTTI or some other mechanism. I would also recommend overloading the sig_hdlr, so you can gracefully shutdown in case something runs-a-muck.
Hope this helps, -Tim
On 11/1/07, Christoph
wrote: I am experimenting with Boost.Serialization. I tried to de-serialize a (binary) file written for a *different* class. Obviously, this can not work.
However, there is not thrown an exception. Question: (How) can I determine that the reading failed? (In case of corrupted or non-matching archives.)
(I have attached a small demo.)
Best regards Christoph
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Regards, Timothy St. Clair [timothysc@gmail.com]
Hello, It's a question that perhaps has little to do with boost, but I guess the boosters must be able to help me. :-) The question is: I want to have an iterator of a std::list type that denotes a NULL iterator, which means the iterator points to nothing, and is obviously different from list::end(), which points to the pass-the-end of a list. I'm using the following code: list<int> alist; alist.push_back(1); list<int>::iterator it_NULL; // denotes a NULL iterator list<int>::iterator it_beg = alist.begin(); std::cout << boolalpha; std::cout << "(it_NULL == it_beg) " << (it_NULL == it_beg) << endl; I got correct result under VS 2003, but under VS2005, I got an runtime error. The cause of the error seems to be I could not compare 2 iterators that don't belong to the same container. I have looked up the C++ 98 standard, and there seems not to be such a restriction for 2 iterators of the same type in comparasion should belong to a same container. What's wrong? Or any other alternative solution available? Thanks in advance for any help. Max
Hi, I'm not sure to understand the goal of your test iterator comparison but if it's to test a list emptiness why not just using alist.empty()? In my understanding a list iterator is not designed to be NULL. But the object it points to could be null and thus you should better test the object than the iterator. Hope it helps, ~Benoi^t LoadCom wrote:
Hello,
It's a question that perhaps has little to do with boost, but I guess the boosters must be able to help me. :-)
The question is: I want to have an iterator of a std::list type that denotes a NULL iterator, which means the iterator points to nothing, and is obviously different from list::end(), which points to the pass-the-end of a list.
I'm using the following code:
list<int> alist; alist.push_back(1);
list<int>::iterator it_NULL; // denotes a NULL iterator list<int>::iterator it_beg = alist.begin();
std::cout << boolalpha; std::cout << "(it_NULL == it_beg) " << (it_NULL == it_beg) << endl;
I got correct result under VS 2003, but under VS2005, I got an runtime error. The cause of the error seems to be I could not compare 2 iterators that don't belong to the same container.
I have looked up the C++ 98 standard, and there seems not to be such a restriction for 2 iterators of the same type in comparasion should belong to a same container.
What's wrong? Or any other alternative solution available? Thanks in advance for any help.
Max
------------------------------------------------------------------------
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hello Dagon Thanks for your reply. I'm not using empty() because what I want to test is not the emptyness of a list, but that of an iterator. Or, in other words, I want to test if an iterator itself doesn't point to any object - that is different from the begin() or end() of a list. ------------------ Max 2007-11-05 ------------------------------------------------------------- 发件人:Benoi^t Dagon 发送日期:2007-11-02 16:34:12 收件人:boost-users@lists.boost.org 抄送: 主题:Re: [Boost-users] [STL] An question about list::iterator Hi, I'm not sure to understand the goal of your test iterator comparison but if it's to test a list emptiness why not just using alist.empty()? In my understanding a list iterator is not designed to be NULL. But the object it points to could be null and thus you should better test the object than the iterator. Hope it helps, ~Benoi^t LoadCom wrote:
Hello,
It's a question that perhaps has little to do with boost, but I guess the boosters must be able to help me. :-)
The question is: I want to have an iterator of a std::list type that denotes a NULL iterator, which means the iterator points to nothing, and is obviously different from list::end(), which points to the pass-the-end of a list.
I'm using the following code:
list<int> alist; alist.push_back(1);
list<int>::iterator it_NULL; // denotes a NULL iterator list<int>::iterator it_beg = alist.begin();
std::cout << boolalpha; std::cout << "(it_NULL == it_beg) " << (it_NULL == it_beg) << endl;
I got correct result under VS 2003, but under VS2005, I got an runtime error. The cause of the error seems to be I could not compare 2 iterators that don't belong to the same container.
I have looked up the C++ 98 standard, and there seems not to be such a restriction for 2 iterators of the same type in comparasion should belong to a same container.
What's wrong? Or any other alternative solution available? Thanks in advance for any help.
Max
------------------------------------------------------------------------
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi,
On 11/5/07, LoadCom
Or, in other words, I want to test if an iterator itself doesn't point to any object - that is different from the begin() or end() of a list.
From my little understanding of the rationale behind such a behavior, following is my take on it.
1. The iterator is a pattern to fetch the content/s of a container 2. Hence, it really points to a location. It could either be the first entry (begin), something till the last (including the last element) or beyond to signify the end of the container I do feel it would be right to have an iterator pointing to nowhere. Maybe an uninitialized state would make sense but that would be like have a similar state for a boolean. The boolean can either be true or false, you do not have a third state to say that it was not initialized. Maybe, the boost::tribool is the outcome of such a requirement, I am just guessing though. -dky -- Dhruva Krishnamurthy Contents reflect my personal views only!
Hi,
Sorry for the typo in my previous posting which conveyed the opposite!
On 11/5/07, dhruva
Hi,
On 11/5/07, LoadCom
wrote: Or, in other words, I want to test if an iterator itself doesn't point to any object - that is different from the begin() or end() of a list.
From my little understanding of the rationale behind such a behavior, following is my take on it.
1. The iterator is a pattern to fetch the content/s of a container 2. Hence, it really points to a location. It could either be the first entry (begin), something till the last (including the last element) or beyond to signify the end of the container
I do feel it would be right to have an iterator pointing to nowhere.
I do NOT feel it would be right to have an iterator pointing to nowhere.
Maybe an uninitialized state would make sense but that would be like have a similar state for a boolean. The boolean can either be true or false, you do not have a third state to say that it was not initialized. Maybe, the boost::tribool is the outcome of such a requirement, I am just guessing though.
-dky -- Dhruva Krishnamurthy Contents reflect my personal views only!
Hi, Krishnamurthy,
Perhaps the tribool is a good counterpart of type bool,
the underminent condition of a tribool for bool type is just
as an uninitialized iterator, it_NULL, for an iterator type
I'm looking for.
Thanks.
Max
Hi,
On 11/5/07, LoadCom
Or, in other words, I want to test if an iterator itself doesn't point to any object - that is different from the begin() or end() of a list.
From my little understanding of the rationale behind such a behavior, following is my take on it.
1. The iterator is a pattern to fetch the content/s of a container 2. Hence, it really points to a location. It could either be the first entry (begin), something till the last (including the last element) or beyond to signify the end of the container I do feel it would be right to have an iterator pointing to nowhere. Maybe an uninitialized state would make sense but that would be like have a similar state for a boolean. The boolean can either be true or false, you do not have a third state to say that it was not initialized. Maybe, the boost::tribool is the outcome of such a requirement, I am just guessing though. -dky -- Dhruva Krishnamurthy Contents reflect my personal views only! _______________________________________________
Max, VS2005 uses checked iterators. The additional checking prevents many misuses of STL containers.
list<int> alist; alist.push_back(1);
list<int>::iterator it_NULL; // denotes a NULL iterator list<int>::iterator it_beg = alist.begin();
std::cout << boolalpha; std::cout << "(it_NULL == it_beg) " << (it_NULL == it_beg) << endl;
Here it_begin is an iterator to the alist container, and it_NULL is an iterator that does not have an associated container. Since the iterators point to different containers, they cannot be compared. This is a good thing :-)
What's wrong? Or any other alternative solution available? Thanks in advance for any help.
The checked iterators kept you from doing something that you shouldn't be doing. You can turn off checked iterators by throwing some defines during compilation (I think any third-party libs that you link to would have to throw the same defines). Trust me when I say that you do not want to turn checked iterators off. It is quite embarrassing how many times checked iterators have found silly bugs in my code :-) I would suggest coming up with a different construct to test for NULL. Justin
LoadCom wrote:
The question is: I want to have an iterator of a std::list type that denotes a NULL iterator, which means the iterator points to nothing, and is obviously different from list::end(), which points to the pass-the-end of a list.
Why is it so "obviously different"? Just like NULL is a special pointer value denoting a pointer that does not reference a valid object, so too the last iterator of a given range [first, last) is an iterator that does not reference any object within the range. Why not do this: list<int>::iterator it_NULL = alist.end(); list<int>::iterator it_beg = alist.begin(); // ... std::cout << "(it_NULL == it_beg) " << (it_NULL == it_beg) << endl; Moshe
The question is: I want to have an iterator of a std::list type that denotes a NULL iterator, which means the iterator points to nothing, and is obviously different from list::end(), which points to the pass-the-end of a list.
I can only think of two possible uses for this (you didn't explicitly mention one) and I don't think either of them should pass any code review. The first one because it doesn't require a special iterator, and the second one because it's *dangerous*. The first one is to see whether and entry in a container is null. This should not require a separate iterator (more work than necessary.) It should merely require that the container be a container of pointers and a check for the value of the stored pointers. The second reason is that you're attempting to erase entries in a container without shrinking/growing the container. In other words, using an inappropriate container as an object pool. All I can say to that is "don't" because this is eradicates all the benefits of using standard containers. If you're having performance problems, think about changing what type of container you're using instead.
Thank you all for the help. I'll consider a new solution according to your suggestions. ------------------ Max 2007-11-19 ------------------------------------------------------------- 发件人:Michael Linck 发送日期:2007-11-10 07:28:32 收件人:boost-users@lists.boost.org 抄送: 主题:Re: [Boost-users] [STL] An question about list::iterator
The question is: I want to have an iterator of a std::list type that denotes a NULL iterator, which means the iterator points to nothing, and is obviously different from list::end(), which points to the pass-the-end of a list.
I can only think of two possible uses for this (you didn't explicitly mention one) and I don't think either of them should pass any code review. The first one because it doesn't require a special iterator, and the second one because it's *dangerous*. The first one is to see whether and entry in a container is null. This should not require a separate iterator (more work than necessary.) It should merely require that the container be a container of pointers and a check for the value of the stored pointers. The second reason is that you're attempting to erase entries in a container without shrinking/growing the container. In other words, using an inappropriate container as an object pool. All I can say to that is "don't" because this is eradicates all the benefits of using standard containers. If you're having performance problems, think about changing what type of container you're using instead. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
binary archives are implemented to be as fast as possible.
There isn't any checking which would impact erformance.
One thing that I've found useful is to check the serialization
using xml archives. Since these have "end" tags, mis-matched
saved/load functions can be detected. This is much harder
in other archives.
Robert Ramey
"Christoph"
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Robert Ramey wrote:
binary archives are implemented to be as fast as possible. There isn't any checking which would impact erformance.
One thing that I've found useful is to check the serialization using xml archives. Since these have "end" tags, mis-matched saved/load functions can be detected. This is much harder in other archives. Yes, that seems to be a good idea. Thank you.
participants (9)
-
Benoi^t Dagon
-
Christoph
-
dhruva
-
KSpam
-
LoadCom
-
Michael Linck
-
Moshe Matitya
-
Robert Ramey
-
Tim St. Clair