Порядок байтов
Наша программа выглядит довольно глупо, но если нам надо послать целое число через побайтовый интерфейс, например по сети, то надо решить, какой байт посылать первым, а какой вторым, и в этом выборе суть проблемы со старше- и младшеконечниками. Другими словами, наша программа неявно выполняет то, что выражение:
fwrite(&x, sizeof(x), 1, stdout);
Делает явным образом. Небезопасно писать (отправлять) int (или short, или long) на одном компьютере и читать это число как int на другом.
Например, если компьютер-передатчик пишет с помощью:
unsigned short x; fwrite(&x, sizeof(x), 1, stdout);
А компьютер-приемник производит чтение так:
unsigned short x; fread(&x, sizeof(x), 1, stdin);
То, если эти компьютеры имеют разный порядок байтов, значение х будет воспроизведено неправильно. Например, если отправлено было число 0x1000, то прочитано оно будет как 0x0010.
Эта проблема часто решается посредством условной компиляции и перестановки байтов, то есть примерно так:
При пересылке большого количества двух – и четырехбайтовых целых такой подход получается слишком громоздким. На практике получается, что байты при пересылке не один раз подвергаются перестановке.
Если ситуация выглядит невесело для short, то для более длинных типов она еще хуже – для них существует больше способов перепутать байты. А если к этому добавить еще всяческие преобразования между членами структур, ограничения на выравнивание и абсолютно таинственный порядок байтов в старых машинах, то проблема покажется 4 просто неразрешимой.
Используйте при обмене данными фиксированный порядок байтов.
Решение проблемы все же существует. Записывайте байты в каноническом порядке, используя переносимый код:
И считывайте их обратно побайтово, собирая первоначальные значения: