#pragma pack (push, 1)
deftype struct {...}
#pragma pack (pop)
ошибка в выравнивании?
Добрый день. Имеется такая проблема: есть консольная программа на си, использующая только средства стандартной библиотеки, которая прекрасно собирается под линукс, при попытке ее сборки под windows, она собирается на дает крайне неправильный результат. В частности выходные файлы получаемые после работы программы при одинаковых входных данных отличаются на несколько килобайт по размеру и соответственно по содержимому (в частности в файле заметно что есть смещение данных). Пока что я грешу на структуру данных которая по sizeof() занимает в linux 2856 байт, а в windows 2864. Как можно разрешить эту проблему?
Компилятор один и тот же (gcc)? Архитектура (i386 vs amd64) одинаковая? На разных архитектурах int и long имеют разную длину. А разные компиляторы могут иметь свои понятия о выравнивании. Если писать в файл, то лучше не int/long, а __u32, __u16, __s8 и им подобные, чтобы при компиляции под любую архитектуру размеры полей структур были одинаковые. А также для структур в файле не плохо отключить выравнивание.
компилятор на линуксе gcc на винде VC. Дистрибутив линукса 32-битный дебиан. винда 7 64-х разрядная.
Код:
Собственно не удивительно. Особенно, что одна система 32-битная, а другая 64.
Не пишите в файл переменные по sizeof, особенно сложные типы. Сериализуйте их в заранее обговоренные по формату файла количество байт. С заранее выбраным порядком байт если пишете числа или же придется сериализовать их в какое то иное представление, позволяющее однозначно восстановить на любой платформе.
Можно конечно и выравнивание отключить. Но если сериализовать все поля структур руками - то эотго не понадобиться и гарантирует контроль над форматом файла.
Но данные внутри то структуры под линуксом равны по размеру данным в структуре под виндой. Проблема при объединении их в структуру, которая начинает отличаться аж на 8 байт.
Ну сказили же - дело в выравнивании. Но в любом случае писать целиком структуру не универсально - хочешь чтоб файл можно было читать везде, сериализуй поля отдельно. И заранее опиши сколько байт каждое поле будет занимать либо в каком виде (например строкой) оно будет сериализоваться.
Спасибо большое, завтра буду пробовать