Проблема с заполнением Big Endian и Little Endian

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


person nsit_poison    schedule 09.11.2011    source источник
comment
Не могли бы вы объяснить, что это за проблема с заполнением? Или, если это обычное явление для проблем с прямым / прямым порядком байтов, проигнорируйте мой комментарий.   -  person CodeCaster    schedule 09.11.2011
comment
на самом деле у меня есть несколько статических массивов размеров, не кратных 4 (код для 32-битных систем). Я исправил их, просто сделав их кратными 8. Я отправляю данные какому-то удаленному клиенту через send ().   -  person nsit_poison    schedule 09.11.2011
comment
Нет, порядок байтов не влияет на заполнение. Член структуры имеет тот же размер, только порядок байтов отличается. Предполагая, что оба компилятора согласны с размером. Проблемы такого рода сделали XML очень популярным.   -  person Hans Passant    schedule 09.11.2011
comment
Если вы также используете битовые поля в своей структуре, вы также можете столкнуться с проблемами с порядком битов и заполнением на этом уровне. Если это проблема для вас, дайте мне знать, я могу уточнить.   -  person Johan Bezem    schedule 09.11.2011


Ответы (2)


Вам нужно иметь в виду следующее:

  • При обмене данными важен порядок байтов протокола связи. Все протоколы передачи данных имеют (должны иметь) указанную последовательность байтов. Вероятно, наиболее распространенным является метод прямого порядка байтов, потому что в те времена, когда вычисления CRC выполнялись с использованием цифровых электронных схем, а не программного обеспечения, сама контрольная сумма должна была быть прямым порядком байтов.

(Это может привести к появлению довольно непонятных протоколов, таких как промышленная стандартная полевая шина CANopen, где все целые числа в отправляемых данных должны иметь прямой порядок байтов, но идентификатор и контрольная сумма должны иметь прямой порядок байтов.)

  • Заполнение структуры всегда будет вызывать проблемы при написании переносимого кода. Код типа send(&my_struct, sizeof(my_struct) никогда не переносится! Потому что он отправит данные и любые байты заполнения. И байты заполнения могут быть где угодно внутри структуры, а не только в конце. Если вам нужно написать действительно переносимый код, вы не можете использовать структуры / объединения для протокола данных, все должно храниться в массивах байтов или аналогичных, где данные гарантированно будут размещены в соседних ячейках. . Заполнение структуры не имеет ничего общего с порядком байтов, а скорее с набором инструкций ЦП.

(Процессоры Motorola традиционно имели лучшую поддержку чтения и сохранения по невыровненным адресам, в то время как производные от Intel предъявляют требования к выравниванию и, следовательно, более склонны к использованию заполнения. Как оказалось, Motorola была с прямым порядком байтов, а Intel - с прямым порядком байтов. Итак, по совпадению у ЦП с прямым порядком байтов больше шансов иметь заполнение, но это только из-за набора инструкций ЦП, а не из-за самого байта.)

person Lundin    schedule 09.11.2011

Структура в C - это способ представления данных в памяти. (Это придает «структуру» памяти.)

Любое преобразование из «структуры» в «последовательность байтов», которое просто отбрасывает бит «структура» и использует любое базовое представление байта, которое использует C, будет зависеть от порядка байтов. (И отступы. Может быть, и другие проблемы, такие как указатели, sizeof (некоторый интегральный тип) и т. Д.)

Я подозреваю, что вы делаете что-то вроде этого:

// Some non-standard way to get rid of padding in Foo
struct Foo
{
  // Some fields...
}

// Meanwhile, in a function somewhere...
fwrite(a_foo, sizeof(a_foo), 1, fp);

Может быть, вы не вызываете fwrite, может быть, send, но да, если вы выполняете сериализацию таким образом, на вас влияет порядок байтов.

person Thanatos    schedule 09.11.2011
comment
Да, ваше предположение верно. На самом деле у меня есть несколько статических массивов размеров, не кратных 4 (код для 32-битных систем). Я исправил их, просто сделав их кратными 8. Я отправляю данные какому-то удаленному клиенту через send (). - person nsit_poison; 09.11.2011