David Raulo wrote:
On Thu, 25 Feb 2010 08:49:50 -0800 "Robert Ramey"
wrote: The signature for loading is:
void load(Archive & ar, T & t, const version){
Maybe it would be a good idea to change this signature to reflect the actual contract on version numbers, so new users can not miss it.
This appeals to me very much. I would like to change it to template<class Archive> void load(Archive &ar, T &t, const uint_least8 version){ } But this would provoke a large number of warnings and another huge chorus of complaints. So I would probably not do this.
in addition, there is a serialization library version returned with get_library_version. This is used internally by the library to address changes in serialization of primitives and other types for which class information is not kept in the archive. I believe that this version # is now up to 4.
Did this number change with boost 1.42? If yes I could use it to detect these archives and work around my problem.
It didn't. But we could change it for boost 1.43 if that would help. I think it's only at 4 so we have 251 to go. At current rate of change, that should last about 500 more years.
Their usage of the version number presumed a 32 bit integer. binary archives only use 16 bits. So their change would make it impossible for them to use binary archives.
Actually, we did encounter this problem with binary archive early on, and we found that binary archive stored the class version as 8 bits (not 16).
Hmmm perhaps I mis-remembered.
I guess I should have posted about this then. But this was not a regression (AFAICT binary archives always behaved like this), and it made sense that in a binary format you may want to save every last byte. So we switched wo XML, and did not report about it here since we assumed to be safe. I understand now that you did not anticipate our usage.
Also, it has always been a fundamental goal of the library that serialization not be tied to a particular type of archive. That is, any serialization functions which world with one type of achive should work with any other. The explains things why serialization of wstring is a part of arhive_?text even though some have considered this as a mistake. Leaving a max version of 8 (or 16) in the binary_archive while using 32 bits in the text archives means that you can't now use binary archives. It never occured to me than anyone would want to couple these two concepts - archive and serialization.
About binary archives, I just did a test, and with boost 1.42 we now get an exception:
/opt/boost-1_42_0/include/boost/archive/basic_binary_oarchive.hpp:83: void boost::archive::basic_binary_oarchive<Archive>::save_override(const boost::archive:\ :version_type&, int) [with Archive = boost::archive::binary_oarchive]: Assertion `t.t <= boost::integer_traits<unsigned char>::const_max' failed.
and this is while saving an object with version 300 to a binary archive (100 works as expected). With an xml archive, and a version number of 100000, no exception, and the version is truncated to 16 bits.
well, that's inconsistent of course. I'll look into it.
Assuming the use classes are not changed, why program built with 1.41 cannot read archive created by 1.42?
It can.
Not in my case. That's how I initially discovered the problem. The class version properties in XML archives generated by 1.42 were truncated to 16 bits, and so could not be read back (with either 1.41 or 1.42).
OK - it can - except in your case.
In this particular case, the situation is that a program built with 1.42 cannot read an archive created by 1.41
yes, and I understand that.
I realise that. But I was answering a person how didn't understand that.
BTW there is still something I do not understand here. Here is an archive generated with boost 1.42 :
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <!DOCTYPE boost_serialization>
<vec class_id="0" tracking_level="0" version="0"> <count>2</count> 100000 <item class_id="1" tracking_level="1" version="34464" object_id="_0"> <value>1</value> </item> <item object_id="_1"> <value>1</value> </item> </vec>This is an STL vector of objects having BOOST_CLASS_VERSION(100000). The class version is truncated, but the "original" number appears as the item_version just above. How did that happen?
lol - here is how that happened. In this case we have two version # floating around here. One is the version# of the container while the other is the version # of the container's item. Since the vector serialization has the capability to "shortcut" the normal process of doing the serializaiton item by item we need to create a data item called "item_version". This is just like any other data item so it could have any type. Of course it should have had the same type of the internal version type - but apparently this was an oversight.
Is there any way I can access this item_version ?
Look into the code for serialization of collections. I doubt there is an easy way to get at it.
Thanks for your help,
Sorry haven't been able to be more helpful. I'm still considering this. You could fix the problem by tweaking the library to permit reading of old archives and re-serializing them under the new system. I realize that this would be a pain but it would work. Also it's not clear that you need to upgrade at all. The changes in the library for the last couple of versions are mostly related to doing thread-safe serialization of types defined in DLLS. This is a whole other can of worms. If you're not doing this, I don't see you'll gain much by using the more recent library.
David.