В моем коде есть структура, у которой есть проблемы с заполнением. Я исправил их, и мой код работает нормально на машине с прямым порядком байтов. Может ли быть шанс, что эта структура вызовет проблему для машины с прямым порядком байтов?
Проблема с заполнением Big Endian и Little Endian
Ответы (2)
Вам нужно иметь в виду следующее:
- При обмене данными важен порядок байтов протокола связи. Все протоколы передачи данных имеют (должны иметь) указанную последовательность байтов. Вероятно, наиболее распространенным является метод прямого порядка байтов, потому что в те времена, когда вычисления CRC выполнялись с использованием цифровых электронных схем, а не программного обеспечения, сама контрольная сумма должна была быть прямым порядком байтов.
(Это может привести к появлению довольно непонятных протоколов, таких как промышленная стандартная полевая шина CANopen, где все целые числа в отправляемых данных должны иметь прямой порядок байтов, но идентификатор и контрольная сумма должны иметь прямой порядок байтов.)
- Заполнение структуры всегда будет вызывать проблемы при написании переносимого кода. Код типа
send(&my_struct, sizeof(my_struct)
никогда не переносится! Потому что он отправит данные и любые байты заполнения. И байты заполнения могут быть где угодно внутри структуры, а не только в конце. Если вам нужно написать действительно переносимый код, вы не можете использовать структуры / объединения для протокола данных, все должно храниться в массивах байтов или аналогичных, где данные гарантированно будут размещены в соседних ячейках. . Заполнение структуры не имеет ничего общего с порядком байтов, а скорее с набором инструкций ЦП.
(Процессоры Motorola традиционно имели лучшую поддержку чтения и сохранения по невыровненным адресам, в то время как производные от Intel предъявляют требования к выравниванию и, следовательно, более склонны к использованию заполнения. Как оказалось, Motorola была с прямым порядком байтов, а Intel - с прямым порядком байтов. Итак, по совпадению у ЦП с прямым порядком байтов больше шансов иметь заполнение, но это только из-за набора инструкций ЦП, а не из-за самого байта.)
Структура в 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
, но да, если вы выполняете сериализацию таким образом, на вас влияет порядок байтов.