Порядковый код в реальном приложении? - PullRequest
3 голосов
/ 29 марта 2011

Я знаю, что следующий код C зависит от порядка байтов:

short s_endian = 0x4142;
char c_endian = *(char *)&s_endian;

На машине с прямым порядком байтов c_endian будет 'A' (0x41);в то время как на машине с прямым порядком байтов это будет 'B' (0x42).

Но этот код кажется уродливым.Так есть ли в реальных приложениях код, зависящий от байтов?Или вы сталкивались с каким-либо приложением, которое нуждается в большом количестве изменений при портировании на другую цель с другим порядком байтов?

Спасибо.

Ответы [ 6 ]

2 голосов
/ 29 марта 2011

Практически любой код, который имеет дело с сохранением целых чисел с более чем 8 битами в двоичном формате или посылает такие целые числа по сети.Для одного чрезвычайно распространенного примера многие поля в заголовке TCP попадают в эту категорию.

1 голос
/ 29 марта 2011

Сетевой код зависит от порядкового номера (он должен всегда передаваться через сеть как big-endian, даже на машине с прямым порядком байтов), поэтому необходимы такие функции, как htons(), htonl(), ntohs() и ntohl() in net/hton.h, которые позволяют легко преобразовывать байтовый порядок хост-сеть и байтовый порядок сеть-хост.

Надеюсь, это поможет,

Jason

0 голосов
/ 31 марта 2011

Если ваша программа отправляет данные в другую систему (либо по последовательному или сетевому каналу, либо сохраняя их в файл для чтения чего-либо еще), либо считывает данные из другой системы, у вас могут возникнуть проблемы с порядком байтов.

Я не знаю, что статический анализ мог бы обнаружить такие конструкции, но если ваши программисты следуют стандарту кодирования, где элементы структуры и переменные были размечены, чтобы указать, что их порядковый номер может помочь.

ДляНапример, если ко всем структурам сетевых данных добавлено _be к названию многобайтовых членов, вы можете найти случаи, когда вы присваивали одной переменной без суффикса (порядок байтов хоста) или даже литеральное значение (например, 0x1234)из этих членов.

Было бы замечательно, если бы мы могли зафиксировать порядок байтов в наших типах данных - uint32_be и uint32_le, чтобы идти с uint32_t.Тогда компилятор может запретить присваивания или операции между ними.И подпись для htobe32 будет uint32_be htobe32( uint32_t n);.

0 голосов
/ 29 марта 2011

Управляя внутренним представлением чисел с плавающей запятой, вы можете получить доступ к частям (или к полному значению), используя целочисленный тип. Например:

union float_u
{
  float f;
  unsigned short v[2];
};

int get_sign(float f)
{
  union float_u u;
  u.f = f;
  return (u.v[0] & 0x8000) != 0;     // Endian-dependant
}
0 голосов
/ 29 марта 2011

Краткий ответ - да. Все, что читает / записывает необработанный двоичный файл в файл или сокет, должно отслеживать последовательность данных.

Например, протокол IP требует представления с прямым порядком байтов.

0 голосов
/ 29 марта 2011

Однажды я собрал данные с помощью специальной карты DAQ на ПК и попытался проанализировать файл на компьютере PowerPC mac.Оказывается, «формат файла», который использовался, был дамп сырой памяти ...

Little endian на x86, big endian на Power PC.Вы это понимаете.

...