Ошибка в выравнивании?
Модератор: Модераторы разделов
-
qmor
- Сообщения: 23
- ОС: debian squeeze
Ошибка в выравнивании?
Добрый день. Имеется такая проблема: есть консольная программа на си, использующая только средства стандартной библиотеки, которая прекрасно собирается под линукс, при попытке ее сборки под windows, она собирается но в результате работы дает крайне неправильный результат. В частности выходные файлы получаемые после работы программы при одинаковых входных данных отличаются на несколько килобайт по размеру и соответственно по содержимому (в частности в файле заметно что есть смещение данных). Пока что я грешу на структуру данных которая по sizeof() занимает в linux 2856 байт, а в windows 2864. Как можно разрешить эту проблему?
-
watashiwa_daredeska
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Ошибка в выравнивании?
* Никогда, совсем никогда, не вводите и не выводите структуры в файл/сокет/пайп/т.п напрямую. Вводите и выводите только по отдельным полям. Это позволит:
- Легко правильно обрабатывать endianness архитектуры.
- Избавиться от проблем с выравниванием полей структуры.
Мои розовые очки
-
qmor
- Сообщения: 23
- ОС: debian squeeze
Re: Ошибка в выравнивании?
* Никогда, совсем никогда, не вводите и не выводите структуры в файл/сокет/пайп/т.п напрямую. Вводите и выводите только по отдельным полям. Это позволит:
1. Легко правильно обрабатывать endianness архитектуры.
2. Избавиться от проблем с выравниванием полей структуры.
* В Windows не забывайте открывать файлы в binary mode.
Спасибо, стало гораздо лучше. сейчас уже не настолько серьезные разногласия. в частности хотя бы размер файлов стал одинаковый. Внутри правда есть небольшое отличие примерно на пару килобайт, а так около 99 процентов файла идентичны эталону. И все же размеры структуры отличаются. как бы это поправить?
-
watashiwa_daredeska
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Ошибка в выравнивании?
Если выводить так, как я сказал, то размер структуры пофиг должен быть. Однако, иногда приходится подгонять типы полей, ибо в C/C++ они могут иметь разные размеры. Либо использовать типы из stdint.h (не знаю, как с ним в компайлерах/библиотеках MS).
Если уж совсем свербит в одном месте, то явно указывать alignment: gcc, msvc.
Мои розовые очки
-
qmor
- Сообщения: 23
- ОС: debian squeeze
Re: Ошибка в выравнивании?
watashiwa_daredeska писал(а): ↑28.09.2010 19:20Если выводить так, как я сказал, то размер структуры пофиг должен быть. Однако, иногда приходится подгонять типы полей, ибо в C/C++ они могут иметь разные размеры. Либо использовать типы из stdint.h (не знаю, как с ним в компайлерах/библиотеках MS).
Если уж совсем свербит в одном месте, то явно указывать alignment: gcc, msvc.
Я тоже думал что размеры полей может быть отличаются. Ан нет, полностью одинаковы. попробую сейчас alignment.
-
NickLion
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: Ошибка в выравнивании?
Можете привести код самой структуры, которую сериализуете?
PS и заодно как это делаете
PS и заодно как это делаете
-
qmor
- Сообщения: 23
- ОС: debian squeeze
Re: Ошибка в выравнивании?
Код: Выделить всё
struct recOneData {
char label[3][84];
char constName[400][6];
double timeData[3];
long int numConst;
double AU;
double EMRAT;
long int coeffPtr[12][3];
long int DENUM;
long int libratPtr[3];
};пока что я просто выставил в MVC компиляторе опцию Zp1 и это вроде помогло.
-
watashiwa_daredeska
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Ошибка в выравнивании?
Следует понимать, что выравнивание полей придумано далеко не зря — с выровненными структурами программа работает быстрее. Иногда несущественно, а иногда и в разы.
Мои розовые очки
-
NickLion
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: Ошибка в выравнивании?
Так:
1. Тип long int имеет размер 32 бита на 32-битной платформе Win/Linux для MVC++ и GCC, но на 64-х битной под виндой 32 бита, а вот в Linux - 64 бита.
2. Zp1 - не стоит делать. Уж лучше:
А вот насчёт падения скорости watashiwa_daredeska более чем прав.
1. Тип long int имеет размер 32 бита на 32-битной платформе Win/Linux для MVC++ и GCC, но на 64-х битной под виндой 32 бита, а вот в Linux - 64 бита.
2. Zp1 - не стоит делать. Уж лучше:
Код: Выделить всё
#pragma pack(push,1)
struct recOneData {...};
#pragma pack(pop)А вот насчёт падения скорости watashiwa_daredeska более чем прав.
-
qmor
- Сообщения: 23
- ОС: debian squeeze
Re: Ошибка в выравнивании?
NickLion писал(а): ↑30.09.2010 12:27Так:
1. Тип long int имеет размер 32 бита на 32-битной платформе Win/Linux для MVC++ и GCC, но на 64-х битной под виндой 32 бита, а вот в Linux - 64 бита.
2. Zp1 - не стоит делать. Уж лучше:
Код: Выделить всё
#pragma pack(push,1) struct recOneData {...}; #pragma pack(pop)
А вот насчёт падения скорости watashiwa_daredeska более чем прав.
Большое спасибо