Почему memcpy "переворачивает" байты? С++
Предположим есть набор сырых, никак не интерпретируемых байт, которые хранятся в массиве raw_bytes
// Последовательность из двух байтов. 0 и
unsigned char raw_bytes[] {0, 1};
Такая последовательность байт в памяти должна выглядеть как 0000.0000 0000.0001. При попытке скопировать два байта в одну переменную типа unsigned short int столкнулся с проблемой, что memcpy переворачивает байты:
unsigned char bts[]{0, 1};
unsigned short int i;
memcpy(&i, bts, 2);
Здесь i будет равняться не 1, а 256. Почему так и как этого избежать? Не нужно предлагать мне решения с reinterpret_cast вместо memcpy, поскольку мне нужно интерпретировать массив байт по-разному во время выполнения, а не во время компиляции.
P.S. Только что наткнулся на эндианность, видимо, это то, что нужно. Если это так, то вопрос меняется. Нужно ли беспокоиться о совместимости с разными эндианами и как это сделать?
Ответы (1 шт):
По итогам комментариев ответ такой - беспокоиться за разный порядок байт можно и нужно, если происходит обмен данными между разными системами. Решения обычно такие:
В компьютерных сетях:
Разработчики договорились, что данные передаются в так называемом сетевом порядке байт, после чего, во всех реализациях сокетов Беркли на C для всех платформ появились функции hton*, ntoh* которые делают необходимую конвертацию (или не делают, если порядок байт на хосте совпадает с сетевым порядком).
Для этого даже придумали стандарт и называется он XDR
Еще одним способом безопасно гонять данные между системами, является перегон их в какой-то текстовый формат, например JSON или XML. Разумеется, выходной файл от этого раздуется и будет грузится не так быстро, как бинарник, но зато решение лепится на коленке очень быстро и гарантированно работает.
Если вы создаете какой-то свой бинарный формат, можете выбирать один из перечисленных выше вариантов - писать XDR, конвертировать в тексты, или просто договориться, что в версиях для других платформ придется делать конвертацию.