Есть две структуры:
typedef struct READ_ENERGY_EXT
{
unsigned char array_num;
unsigned char month_num;
unsigned char tarif_num;
unsigned char mask;
unsigned char format;
double Ap;
double Am;
double Rp;
double Rm;
double R1;
double R2;
double R3;
double R4;
} ENERGY_REG;
typedef struct READ_FLASH_POWER
{
unsigned char power_type;
unsigned char phase_num;
double P[4];
double Q[4];
double S[4];
} FLASH_POWER;
при компиляции gcc 4.0.1
sizeof(ENERGY_REG) - 72
sizeof(FLASH_POWER) -100
при копмиляции C++ Builder
sizeof(ENERGY_REG) - 72
sizeof(FLASH_POWER) -104
насколько я знаю стукрура выравнивается что бы итоговый
размер был кратный наибольшему типу в структуре, то есть
в случае второй структуры кратным 8(double), как это делает Builder,
почему же тогда gcc делает 100 байт. При чем, причем всякие там
#pragma pack(push, 8) и __attribute__((aligned(8))) дело не меняют,
все равно 100 байт. Менять опцию оптимизации(-O) пробовал, тоже самое.
Необходимо перебавать структуры через сокеты с lin сервера на win
клиент. Выравнивать по байту неохото ибо потеряю в производительности,
и конвертировать стуктуру в строку тоже, т.к. структур много, да и не
использовать удобную функцию сокетного send`a тоже
не то... , получиться, если б я убрал выравнивание, мало того, что это придётся делать в обоих средах, ещё и упадёт произвадительность, в принципе временно проблему я решил путем выравнивания структуры READ_FLASH_POWER по 4 байтам в Builder`е, но просто интересно почему гнутый копмилятор выравнивает по 4 байта, когда должет по 8, да ещё не слушает, меняющие это, директивы
> насколько я знаю стукрура выравнивается что бы итоговый
размер был кратный наибольшему типу в структуре
а насколько я знаю, компилятор может выравнивать как хочет :) Грубо говоря, он может вообще поменять местами все поля структуры кроме первого. В стандарте есть только одно требование - адрес первого поля структуры долен совпадать с адресом самой структуры.
а писать код, зависящий от выравнивания - IMHO плохой стиль.
>а насколько я знаю, компилятор может выравнивать как хочет :)
но как может быть такое, что две подобные структуры в инициализируемые подряд, он выравнивает по разному.
>а писать код, зависящий от выравнивания - IMHO плохой стиль.
это понятно, но так меньше гемора с транспортировкой данных через сокеты.
>-malign-double
думаю не подойдёт, т.к. распространяется на весь код, а необходимо выровнять часть структур, кто му же получится оптимизация под пентиум, а целевая система будет Geode. И ещё настораживает:
> Предупреждение: Если вы используете опцию '-malign-double', структуры, содержащие выше перечисленные типы будут выравниваться не так, как в опубликованных спецификациях прикладного двоичного интерфейса для 386.
> насколько я знаю стукрура выравнивается что бы итоговый
размер был кратный наибольшему типу в структуре, то есть
в случае второй структуры кратным 8(double), как это делает Builder,
почему же тогда gcc делает 100 байт.
касательно размера - это union
выравнивание относится не к размерам объектов а к адресам (виртуальным) по которым они расположены
проверил (хотя gcc 3.4.3) - без выравнивания 100 с выравниванием 104 - всё как надо
>это понятно, но так меньше гемора с транспортировкой данных через сокеты.
сериализация и десериализация мало того что не сильно подорвёт производительность при передаче через сетевые сокеты, она ещё даст возможность менять компиляторы, платформу и язык программирования (например, сервер на java). Не хотел бы я поддерживать код зависящий от версии gcc (а завтра программу постявят на итаниум, чего будешь делать ?).
Как обычно программисты ищут проблемы и потом мужественно их решают.
> > это понятно, но так меньше гемора с транспортировкой данных через сокеты.
> Это о-малое от геморра, который поимеет программер, решивший в данном проекте поменять компилятор / платформу.
Опять? Вы где этого наслушались? На лекциях? Блин. Структуры при IO использовать можно и в инекоторых случаях необходимо. Примеров куча -- IP, X11, бинарные форматы (tar, elf, bmp, ...).
> Код зависит от gcc у тех, кто писать не умеет. Еще раз смотри на примеры правильного использования структур при IO.
Я утверждаю, что не существует правильного способа без сериализации записывать структуры в байтовый поток (файл или сокет) на языке С\С++. Правильный означает - чтобы код без изменений компилировался и работал под произвольной платформой, где например упакованные структуры невозможны в принципе, или где другой поряок байтов в целых числах.
Если вы с этим не согласны, приведите пример кода (конкертный текст или ссылку), где структура напрямую пишется\читается.
Бла-бла-бла. Ты приводишь свои утверждения ни на что не опираясь. Кто сказал что это сложно и вредно?! Опыт показывает, что это проще и быстрее чем сериализация. Где тут вред? Вред от тех, кто инструментом пользоваться не умеет.
В прошлом треде я целый день распинался перед вами, теоретиками, ссылки давал, цитаты. Теперь вот по второму кругу. Да вы не пробиваемы. Ворчите себе под нос как психи: "структуры, нельзя, нельзя, структуры, нельзя, нельзя, нельзя". Где вы такое заучили?
"Еще моя гипотеза: мозг Шарика в собачьем периоде его жизни накопил бездну понятий. Все слова, которыми он начал оперировать в первую очередь, - уличные слова, он их слышал и затаил в мозгу. Теперь, проходя по улице, я с тайным ужасом смотрю на встречных псов. Бог их знает, что у них таится в мозгах." (c) Собачье сердце
Я-то, как раз, в этом смысле практик, давно вышедший из пыонэрского возраста. Поэтому и пытаюсь нейтрализовать вредное влияние на неокрепшие умы подобных тебе экстремистов;)
> Опыт показывает, что это проще и быстрее чем сериализация.
А еще опыт показывает, что при сборках разными компиляторами в таких ситуациях возникают ТАКИЕ жопы, что проще удавиться. Я однажды разгребал такую ситуацию - и закончилось все сериализацией.
какая горячая дискуссия развернулась :-), я считаю, что сериализация правильней, чем ручное выравнивание структур, но как я говорил уже, нужно было, что б "сейчас работало", в дальнейшем придёться переделывать т.к. платформа в дальнейшем будет другая... да и вообще, разная. Интересно собственно было, почему gcc не хочет выравнивать вторую стукруту по 8 байтам, а только либо по 4(как я понял по умолчанию), либо меньше(по 1 работает), при чем не помогает ни одна из директив (#pragma pack(push, 8) , #pragma pack(8) , __attribute__((aligned(8)))
> В прошлом треде я целый день распинался перед вами, теоретиками, ссылки давал, цитаты.
Твои примеры (xorg) и есть примеры сериализации, в _реализации_ которой для задания отступов полей применяются структуры.
> Теперь вот по второму кругу. Да вы не пробиваемы. Ворчите себе под нос как психи: "структуры, нельзя, нельзя, структуры, нельзя, нельзя, нельзя". Где вы такое заучили?
Тебе сказали, что можно, а ты остановиться не можешь.
Вы согласны, что переносимым образом невозможно сделать
write (fd, &a_struct, buff_len); // на 1 хосте
read (fd, &a_struct, buff_len); // на 2 хосте
use(a_struct.some_field);
как структуру не опиши?
> Вы согласны, что переносимым образом невозможно сделать
Согласен, конечно. Однако, если структура кратна машинному слову или за'pad'ина до кратности, то структура это или нет не играет никакой роли. Потому как надо всегда договариваться об endianess -- так делают в любом бинарном протоколе. Так делают в любом текстовом протоколе, который wchar_t. Так делают в любом socket-aware приложении (htonX). Посылай всё в network byte order и не знай проблем.
Когда передаешь структуру -- ограничений море. И размеры полей, и разное представление отрицательных чисел, и разное представление дробных чисел, и т.д. и т.п. Твоя задача спроектировать протокол так, чтобы "вписаться" в эти ограничения или их обойти (выравнивание, в крайнем случае упаковка, договоренности об endianess, об представлении числа, ...). Но всё это решаемо и является стандартными проблемами при работе на низком уровне. Не хочешь думать об этих проблемах? Тогда не нужно выбирать С в качестве языка разработки.
После прочтения впечатление такое:
чтобы не было неоднозначностей в разбросе или езде полей, Все поля нужно
делать размером в 1 addressable storage unit(ASU).
Если хочется передавать флажки - уже нужно возиться с запихиванием
битов в машинное слово (это уже сериализация :]).
Если ASU - одинаковые на машинах - вроде бы проблем нет,
а если разные, то геморроя получается больше, чем самому паковать
биты в ячейки, равные НОК (ASU всех target машин).
ИМХО не следует переводить дискуссию в чисто терминологическое русло.
logIN утверждает, что для сериализации структур в битовый (ок, байтовый) поток логичнее пользоваться операциями чтения/записи над структурами, а потом их перетасовывать.
Оппоненты (и я, в том числе) утвеждают, что разумнее для этого читать/писать данные неструктурированно и потом распихивать их по полям соответствующей структуры.
ИМХО второй подход, ОЧЕВИДНО, более логичен и прост (хотя бы в силу того, что на разных архитектурах даже упакованные структуры будут иметь различный размер). logIN настаивает (как я понимаю) на первом подходе.
Что ж, гланды тоже можно вырезать автогеном вместо скальпеля, и не обязательно через рот...