Reputation: 10658
I have some serialization logic in which I also serialize stl datastructures. Currently I just write the size field and then each element of the structure by iterating over it. In the deserialization I read the size field and then I know when I am done reading the data structure.
No the question is how to write the size field correctly and system independent. Currently I am using the std::iterator_traits<const_iterator>::difference_type
as the type to store in the file. However I am not sure, if this type is guaranteed to be system independent or if it might change, when I try to exchange files between different systems.
I had a look at this type for std::string
and in this case sizeof(std::iterator_traits<std::string::const_iterator>::difference_type)
returns 8 on a 64 bit machine. So I guess in this case this is just a typedef for size_t
which takes up one word. I do not have a 32 bit machine available here currently so I cannot check if the size is something different on there.
Is this guaranteed by the standard to be portable, or should I use some fixed type for all data structures here to encode the length?
Upvotes: 2
Views: 502
Reputation: 67197
Is this guaranteed by the standard to be portable, or should I use some fixed type for all data structures here to encode the length?
No, it is not portable, and yes, you should use some fixed-size type. For most applications, a 32-bit integer should be fine. Please note that, depending on your serialization code and portability requirements, you could also face byte order issues (little-endian vs. big-endian).
For more information and best practices, look at the documentation of Qt QDataStream
. The Qt people recommend to decide on a fixed-size integer type (such as qint32
), then cast appropriately when serializing.
Upvotes: 2
Reputation: 101484
difference_type
is defined by the Standard to be a "signed integral type" (20.1.5, Table 32) and is required to be a typedef
of type ptrdiff_t
(20.1.5/4), which, in turn, is implementation-defined (5.7/6).
Since the common denominator here is that it is convertible to a "signed integral type", if you need to serialize this value I'd recommend static_cast
'ing it to something like a long
and saving that.
Upvotes: 2
Reputation: 477436
The whole point of all those typedefs is that you do not need to fix the type globally!
For serialization, you will have to decide and fix your serialized format. At that point, you may simply demand that the size fit into a 32-bit integer, test if the given size does and convert. If there's an error, you can just let your serialization fail (e.g. "data structure not serializable"). If you think it's necessary, make the size field 64-bit and you should have plenty of leeway, but it's up to you to weigh space against flexibility and usage profile. Will you really have containers with more than 4 billion elements and write those to disk?
Serializing is about making decisions and publishing prescriptions, and you have to live with and account for the possibility of import and export failures.
Upvotes: 3