URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 4714
[ Назад ]

Исходное сообщение
"корректное наложение структуры на массив"

Отправлено Валерий , 05-Окт-05 12:41 
Возникла одна трабла по С. В UNIX я слабак, раньше программил под Вындовс. Может быть кто то сталкивался с этой проблемой. Мне нужно считать массив char в структуру. Делаю примерно так.

char arr[100];
struct mystruct
{
  char a, int b;
};

struct mystruct *st = (struct mystruct *)arr;

теперь &(st->a) будет = &arr[0], а &(st->b) = &arr[4]
а нужно что бы &(st->b) ссылался на &arr[1].

Как это сделать? Я знаю что в масдаях есть директива компилятора, которая выравнивает структуры по байтам. Как это сделать в gcc? Есть ли такая директива компилятора? Или может быть кто то знает другой эффективный способ корректного наложения структуры на массив?

Заранее благодарен за ответы.


Содержание

Сообщения в этом обсуждении
"корректное наложение структуры на массив"
Отправлено Av , 05-Окт-05 14:00 
#pragma pack(N), в твоем случае N=1 :)

"корректное наложение структуры на массив"
Отправлено Валерий , 05-Окт-05 14:48 
>#pragma pack(N), в твоем случае N=1 :)

Ага, спасибо. Я уже так и сделал и все заработало. Скажите, а на сколько в этом случае упадет производительность? Если я скомпилирую gcc -с -o myfile.o mysile.c, повлияет ли эта дирректива на всю программу или только на объектный файл myfile.o?


"корректное наложение структуры на массив"
Отправлено sandy , 05-Окт-05 15:34 
>>#pragma pack(N), в твоем случае N=1 :)
>
>Ага, спасибо. Я уже так и сделал и все заработало. Скажите, а
>на сколько в этом случае упадет производительность? Если я скомпилирую gcc
>-с -o myfile.o mysile.c, повлияет ли эта дирректива на всю программу
>или только на объектный файл myfile.o?

Я бы компилировал с использованием оптимизатора:
-с -O -o myfile.o mysile.c



"корректное наложение структуры на массив"
Отправлено Av , 05-Окт-05 19:03 
>на сколько в этом случае упадет производительность?

операция выборки выравненый ячеек в памяти насколько я помню быстрее, но это разница на современных потомках 8080 изчезающе мала :)

>Если я скомпилирую gcc -с -o myfile.o mysile.c, повлияет ли эта дирректива на всю программу  или только на объектный файл myfile.o?

#pragma pack(1)
/* выравнивание по байту */
struct ...

#pragma pack()
/* выравнивание по умолчанию :) */


"корректное наложение структуры на массив"
Отправлено Hordi , 13-Окт-05 13:12 
Вспоминая содержимое книги Криса Касперски "Техника оптимизации программ.Эффективное использование памяти",- потери при невыравнивании не такие уж и незначительные...

"корректное наложение структуры на массив"
Отправлено gyn61 , 13-Окт-05 14:49 
А можно и так:

#pragma pack(push, 1)
/* выравнивание по байту */
struct ...

#pragma pack(pop)
/* вернули как раньше было */


"корректное наложение структуры на массив"
Отправлено Alexander S. Salieff , 06-Окт-05 20:32 
>>#pragma pack(N), в твоем случае N=1 :)
>
>Ага, спасибо. Я уже так и сделал и все заработало. Скажите, а
>на сколько в этом случае упадет производительность? Если я скомпилирую gcc
>-с -o myfile.o mysile.c, повлияет ли эта дирректива на всю программу
>или только на объектный файл myfile.o?

Есть такой тонкий момент, что теперь тебе (без очень тонкой настройки кода) заказана работа с нативными GCC'шными STL-контейнерами, содержащими эту структуру, т.к. у них STL'ные либы имеют предкомпиленные (и предкомпиленные безо всяких pragma pack'ов) куски, которые начинают конфликтовать с шаблонными декларациями в твоей проге, короче все кончается очень плохо, абсолютно неразгребаемыми segfault'ами. Девелоперы GCC сказали что эту багу они править не собираются, ибо "использовать в 21ом веке пакованные структуры - это дикость"...

По той же причине очень не рекоммендуется собирать STL'ный плюсовый софт с помощью g++ -fno-pack


"корректное наложение структуры на массив"
Отправлено А , 05-Окт-05 14:13 

union ff {
             char* p;
             mystruct *ms;
      } myunion;

myunion.p = arr;
...

или

union ff {
             char arr[100];
             mystruct *ms;
      } myunion;


"корректное наложение структуры на массив"
Отправлено AlexKiriukha , 11-Окт-05 18:55 
IMHO это самое корректное решение


"корректное наложение структуры на массив"
Отправлено f00l , 12-Окт-05 19:45 
struct mystruct
{
  char a    __attribute__((packed));
  int b     __attribute__((packed));
};

Это просто выровнит одну структуру по размеру.
а #pragma pack(1) выровниит все программу и
уменьшив быстродействие.


"корректное наложение структуры на массив"
Отправлено enot , 13-Окт-05 14:51 
> struct mystruct
>{
>  char a    __attribute__((packed));
>  int b     __attribute__((packed));
>};
>
> Это просто выровнит одну структуру по размеру.
> а #pragma pack(1) выровниит все программу и
> уменьшив быстродействие.

Неа, если писать:
#pragma pack(push,1)
struct _mystruct {
char a;
int b;
};
#pragma pack(pop)
то не все программу, а только конкретную структуру.

Если не поймет, то старая запись:
#pragma pack(1)
struct _mystruct {
char a;
int b;
};
#pragma pack()


Вообще-то правильней использовать __attribute__ так:
struct mystruct {
  char a;
  int b;
} __attribute__((packed));
При упаковке отдельных элементов результат может отличаться от упаковки  всей структуры?

Использование __attribute__ непереносимо под другие компиляторы.

А вот если забыть закрывающий pack, то первый же виртуальный класс выдаст segmentation fault. STL например ))...

Касперски конечно надо почитать... А лучше заранее подумать над алгоритмом. Тогда и оптимизировать не надо будет :)

"использовать в 21ом веке пакованные структуры - это дикость"...
использовать оператор goto тоже, вот только в некоторых случаях лучше выхода чем оператор goto или пакованные структуры еще не придумали.

union тоже выравнивается, так что тоже в pack запихивать надо :)