В одном проекте есть библиотека, используемая также в ряде других проектов подобного толка. В ней есть тип uint128, реализованный вот так:
struct uint128 {
uint64 hi;
uint64 lo;
// и дальше всякие методы и т.д.
};
В этой же библиотеке поддерживается и бинарная сериализация типов. В том числе и этого. При сериализации в бинарном потоке сначала пишется поле hi, потом поле lo, а не наоборот. Покажу, как это выглядит, на примере.
Допустим, переменная:
uint128 x = 1234;
Здеcь hi = 0, lo = 1234 = 4D2.
Сериализация только x.lo выглядела бы так:
D2 40 00 00 00 00 00 00
Как видим, при сериализации байты просто пишутся в обратном порядке.
Если бы x.lo был, к примеру, uint32, то было бы так:
D2 40 00 00
Отсюда логично ожидать, что сериализация x целиком (будь он стандартным типом, а не структурой) будет выглядеть так:
D2 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Но в структуре-то сделали первым
hi. Поэтому имеем:
00 00 00 00 00 00 00 00 D2 40 00 00 00 00 00 00
где первые 8 байт - это тот самый hi, а вторые - это lo.
ИМХО, такие моменты очень сильно затрудняют проектирование чего-либо. Если в библиотеке есть тип, который внешне называется и выглядит как "дополняющий стандартные типы", то и поведения от него ожидаешь как от стандартного. А он ведет себя не так. При отсутствии тестирования можно и баг словить.
У меня большое желание добавить туда свой тип, взяв за основу код uint128 и изменив лишь порядок полей в структуре. Более того, я бы даже не стал делать свой тип, а просто поменял порядок полей в этом типе. Делать так не буду лишь потому, что у проекта много форков, там тоже широко задействована библиотека, а какой-то код можно притащить оттуда и это чревато проблемами, если вот так переделать в библиотеке.
Насколько я неправ, считая, что описанное - просто недодумка авторов столь широко используемой библиотеки?
Я описал, чем хорошо мое расположение полей, а чем и в каком случае оно может быть плохо?