Структуры не формат файла, и вы не должны пытаться использовать их как таковые.
Когда вы пытаетесь заставить структуры работать с fread
и fwrite
, естьогромное количество хаков, чтобы заставить это работать.Вы можете поменять местами целые числа, чтобы вы могли обмениваться файлами между машинами с прямым и прямым порядком байтов.Вы изменяете свои структуры, чтобы использовать целочисленные типы фиксированной ширины, чтобы вы могли делиться между компьютерами с разными размерами слов (например, между машинами x86 и x64).Вы добавляете специфичные для компилятора прагмы, чтобы управлять заполнением структур для обмена версиями компилятора.
Это работает, но уродливо.Не говоря уже о том, что легко ошибиться.
Как и рекомендация в Ошибка порядка следования байтов , гораздо лучшая идея - написать код для чтения / записи полей по отдельности.Написав свой собственный код, вы можете убедиться, что нет заполнения, и вы можете выбирать целочисленные размеры независимо от локального размера целых чисел, и вы можете поддерживать оба порядка байтов без замены байтов (читая / записывая байты целого числа отдельно).
В отличие от хакерского подхода, трудно ошибиться.Кроме того, поскольку вы не полагаетесь на поведение, специфичное для компилятора или архитектуры, либо ваш код будет работать на всех компиляторах и архитектурах, либо ни на одном.Если вы все сделаете правильно, у вас не должно быть ошибок, специфичных для платформы.
Есть один недостаток;индивидуальное чтение / запись полей будет медленнее, чем просто использование fread / fwrite напрямую.Вы можете настроить буфер (uint8_t buffer[]
) и записать в него все данные, а затем записать все сразу, что может помочь, но все равно будет медленнее (потому что вам все равно придется перемещатьполя в буфер по одному), но для большинства целей это все равно будет достаточно быстро (за исключением встроенных систем / систем реального времени или чрезвычайно высокопроизводительных вычислений).