B
B
beem72020-08-01 18:35:13
C++ / C#
beem7, 2020-08-01 18:35:13

Why, when serializing uint128, hi is serialized first, then lo, and not vice versa?

One project has a library that is also used in a number of other similar projects. It has a uint128 type implemented like this:

struct uint128 {
    uint64 hi;
    uint64 lo;
    // и дальше всякие методы и т.д.
};

The same library also supports binary serialization of types. Including this one. When serializing in a binary stream, the hi field is written first, then the lo field, and not vice versa. I'll show you how it looks with an example.
Let's say the variable is: Here hi = 0, lo = 1234 = 4D2. Serializing only x.lo would look like this: As you can see, during serialization, the bytes are simply written in reverse order. If x.lo were, for example, uint32, then it would be like this: Hence, it is logical to expect that the serialization of x as a whole (be it a standard type, not a structure) would look like this: But in the structure, they made hi first . Therefore, we have: where the first 8 bytes are the same hi, and the second are lo.
uint128 x = 1234;
D2 40 00 00 00 00 00 00
D2 40 00 00
D2 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 D2 40 00 00 00 00 00 00

IMHO, such moments make designing something very difficult. If the library has a type that is externally named and looks like "complementing standard types", then you expect it to behave like a standard one. And he doesn't behave like that. In the absence of testing, you can catch a bug.

I have a great desire to add my own type there, taking the uint128 code as a basis and changing only the order of the fields in the structure. Moreover, I would not even begin to make my own type, but simply change the order of the fields in this type. I will not do this just because the project has a lot of forks, the library is also widely used there, and some code can be dragged from there and this is fraught with problems if it is redone in the library like this.

How wrong am I, believing that what is described is just an omission of the authors of such a widely used library?
I described why my field arrangement is good, and why and in what case it can be bad?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
AnT, 2020-08-01
@beem7

This is done because this library is written in accordance with some external specification that you forgot to mention in your question. This external specification says in black and white that this is how it should be done - that's why it's done that way. That's the whole answer. And why this external specification contains such a strange requirement is a question for its authors. Maybe they had good reasons for that, or maybe they just froze stupidity.
In a general setting, the question "why serialize hi first, then lo" is meaningless. No, in general they don't.
Also, your statement "during serialization, the bytes are simply written in reverse order" is not clear. The order from "younger to older" is the natural direct order. There is nothing "reverse" in it.

W
Wataru, 2020-08-01
@wataru

Why serialize like this and not vice versa? It's just the way it is when it's transmitted over the network. Serialization can be used for this as well, which is why the author probably did so.
In fact, you can do as the author of the library wants. At first, write down all even bits, then - odd ones, at least hi / low, at least Low / hi, if some kind of compatibility with other libraries is not required.

M
maaGames, 2020-08-02
@maaGames

Because the structure first says hi, and then lo. Therefore, the bytes of the upper half are stored first, and then the lower half. Why low and hi are arranged like this is a question for the programmers who created the structures.
I agree that this looks like a jamb, because it will not be possible to take a native 128-bit integer and load it from a previously saved file, because the byte order will be wrong. The developers didn't think that 128 bit integers could be added "soon".
If the struct were stored via a struct pointer and sizeof(uint128), then the byte order would be correct and compatible with the potentially added 128 bit integers. So, first of all, this is a cant (library) of the serializer of this structure.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question