Чтобы повторить наиболее существенные моменты: если вы используете это на одной платформе компилятора / HW в качестве только программной конструкции, то проблема с порядком байтов не будет проблемой. Если вы используете код или данные на нескольких платформах ИЛИ должны соответствовать аппаратным битам, то это IS проблема. А много профессионального программного обеспечения является кроссплатформенным, поэтому оно должно заботиться.
Вот самый простой пример: у меня есть код, который хранит числа в двоичном формате на диске. Если я сам не записываю и не читаю эти данные непосредственно на диск, побайтно, то это не будет тем же значением, если он будет прочитан из системы с обратным порядком байтов.
Конкретный пример:
int16_t s = 4096; // a signed 16-bit number...
Допустим, моя программа поставляется с некоторыми данными на диске, которые я хочу прочитать. Скажем, я хочу загрузить ее как 4096 в этом случае ...
fread((void*)&s, 2, fp); // reading it from disk as binary...
Здесь я читаю его как 16-битное значение, а не как явные байты.
Это означает, что если моя система соответствует порядку байтов, хранящемуся на диске, я получу 4096, а если нет, то получу 16 !!!!!
Таким образом, наиболее распространенное использование порядка байтов - это массовая загрузка двоичных чисел, а затем выполнение bswap, если вы не соответствуете. Раньше мы хранили данные на диске с прямым порядком байтов, потому что Intel была странной фигурой и предоставляла высокоскоростные инструкции для обмена байтами. В настоящее время Intel настолько распространена, что часто делает Little Endian по умолчанию и заменяет его в системе с прямым порядком байтов.
Более медленный, но порядковый нейтральный подход состоит в том, чтобы делать ВСЕ ввода / вывода байтами, т. Е .:
uint_8 ubyte;
int_8 sbyte;
int16_t s; // read s in endian neutral way
// Let's choose little endian as our chosen byte order:
fread((void*)&ubyte, 1, fp); // Only read 1 byte at a time
fread((void*)&sbyte, 1, fp); // Only read 1 byte at a time
// Reconstruct s
s = ubyte | (sByte << 8);
Обратите внимание, что этот код идентичен коду, который вы написали бы для обмена с порядком байтов, но вам больше не нужно проверять порядок байтов. И вы можете использовать макросы, чтобы сделать это менее болезненным.
Я использовал пример хранимых данных, используемых программой.
Другое упомянутое основное приложение - это запись аппаратных регистров, где эти регистры имеют абсолютный порядок. Это ОЧЕНЬ ОБЩЕЕ место с графикой. Получите неправильный порядок байтов и ваши каналы красного и синего цвета поменяются местами! Опять же, проблема заключается в переносимости: вы можете просто адаптироваться к конкретной аппаратной платформе и видеокарте, но если вы хотите, чтобы один и тот же код работал на разных машинах, вы должны протестировать.
Вот классический тест:
typedef union { uint_16 s; uint_8 b[2]; } EndianTest_t;
EndianTest_t test = 4096;
if (test.b[0] == 12) printf("Big Endian Detected!\n");
Обратите внимание, что проблемы с битовыми полями также существуют, но они ортогональны проблемам с порядком байтов.