Ошибка в выравнивании?

Модератор: Модераторы разделов

qmor
Сообщения: 23
ОС: debian squeeze

Ошибка в выравнивании?

Сообщение qmor »

Добрый день. Имеется такая проблема: есть консольная программа на си, использующая только средства стандартной библиотеки, которая прекрасно собирается под линукс, при попытке ее сборки под windows, она собирается но в результате работы дает крайне неправильный результат. В частности выходные файлы получаемые после работы программы при одинаковых входных данных отличаются на несколько килобайт по размеру и соответственно по содержимому (в частности в файле заметно что есть смещение данных). Пока что я грешу на структуру данных которая по sizeof() занимает в linux 2856 байт, а в windows 2864. Как можно разрешить эту проблему?
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Ошибка в выравнивании?

Сообщение watashiwa_daredeska »

* Никогда, совсем никогда, не вводите и не выводите структуры в файл/сокет/пайп/т.п напрямую. Вводите и выводите только по отдельным полям. Это позволит:
  • Легко правильно обрабатывать endianness архитектуры.
  • Избавиться от проблем с выравниванием полей структуры.
* В Windows не забывайте открывать файлы в binary mode.
Спасибо сказали:
qmor
Сообщения: 23
ОС: debian squeeze

Re: Ошибка в выравнивании?

Сообщение qmor »

* Никогда, совсем никогда, не вводите и не выводите структуры в файл/сокет/пайп/т.п напрямую. Вводите и выводите только по отдельным полям. Это позволит:

1. Легко правильно обрабатывать endianness архитектуры.
2. Избавиться от проблем с выравниванием полей структуры.

* В Windows не забывайте открывать файлы в binary mode.

Спасибо, стало гораздо лучше. сейчас уже не настолько серьезные разногласия. в частности хотя бы размер файлов стал одинаковый. Внутри правда есть небольшое отличие примерно на пару килобайт, а так около 99 процентов файла идентичны эталону. И все же размеры структуры отличаются. как бы это поправить?
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Ошибка в выравнивании?

Сообщение watashiwa_daredeska »

qmor писал(а):
28.09.2010 17:37
И все же размеры структуры отличаются. как бы это поправить?
Если выводить так, как я сказал, то размер структуры пофиг должен быть. Однако, иногда приходится подгонять типы полей, ибо в C/C++ они могут иметь разные размеры. Либо использовать типы из stdint.h (не знаю, как с ним в компайлерах/библиотеках MS).

Если уж совсем свербит в одном месте, то явно указывать alignment: gcc, msvc.
Спасибо сказали:
qmor
Сообщения: 23
ОС: debian squeeze

Re: Ошибка в выравнивании?

Сообщение qmor »

watashiwa_daredeska писал(а):
28.09.2010 19:20
qmor писал(а):
28.09.2010 17:37
И все же размеры структуры отличаются. как бы это поправить?
Если выводить так, как я сказал, то размер структуры пофиг должен быть. Однако, иногда приходится подгонять типы полей, ибо в C/C++ они могут иметь разные размеры. Либо использовать типы из stdint.h (не знаю, как с ним в компайлерах/библиотеках MS).

Если уж совсем свербит в одном месте, то явно указывать alignment: gcc, msvc.


Я тоже думал что размеры полей может быть отличаются. Ан нет, полностью одинаковы. попробую сейчас alignment.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Ошибка в выравнивании?

Сообщение NickLion »

Можете привести код самой структуры, которую сериализуете?

PS и заодно как это делаете
Спасибо сказали:
qmor
Сообщения: 23
ОС: debian squeeze

Re: Ошибка в выравнивании?

Сообщение qmor »

NickLion писал(а):
29.09.2010 12:32
Можете привести код самой структуры, которую сериализуете?

PS и заодно как это делаете

Код: Выделить всё

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: Ошибка в выравнивании?

Сообщение watashiwa_daredeska »

qmor писал(а):
29.09.2010 12:45
я просто выставил в MVC компиляторе опцию Zp1 и это вроде помогло.
Следует понимать, что выравнивание полей придумано далеко не зря — с выровненными структурами программа работает быстрее. Иногда несущественно, а иногда и в разы.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Ошибка в выравнивании?

Сообщение NickLion »

Так:
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: Ошибка в выравнивании?

Сообщение qmor »

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 более чем прав.

Большое спасибо
Спасибо сказали: