реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> sizeof() странно себя ведёт...
Andy Sm.
сообщение May 12 2008, 12:49
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 27-11-07
Пользователь №: 32 718



Есть структурка.

typedef struct {
unsigned short Version;
unsigned short Hi_Addr;
unsigned short Lo_Addr;
unsigned short CtlReg;
unsigned short H_size;
unsigned short V_size;
unsigned short AccBin;
unsigned short XDelay;
unsigned short CCDTemp;
unsigned short GainDark;
unsigned short Period;
unsigned short Tint;
unsigned short DualRatio;
unsigned short FIFOState;
unsigned short InfoReg;
unsigned short Data[32];
} param;

если написать sizeof (param) то под виндой вернёт 94 (что есть правильно).
а под линухом на ARM_е 96 (что странно по меньшей мере)... =(
GCC 3.3.5.
#pragma pack пробовал, не помогает...

Кто нибудь может сказать как такое может быть?
Go to the top of the page
 
+Quote Post
diper
сообщение May 12 2008, 12:54
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 94
Регистрация: 12-11-05
Из: Росиия, Нижний Новгород
Пользователь №: 10 750



Цитата(Andy Sm. @ May 12 2008, 16:49) *
Кто нибудь может сказать как такое может быть?

Может массив выровнял на гарницу 4 байт?
Go to the top of the page
 
+Quote Post
sff
сообщение May 12 2008, 13:13
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 172
Регистрация: 23-04-06
Пользователь №: 16 404



Цитата(Andy Sm. @ May 12 2008, 16:49) *
если написать sizeof (param) то под виндой вернёт 94 (что есть правильно).
а под линухом на ARM_е 96 (что странно по меньшей мере)... =(
GCC 3.3.5.
#pragma pack пробовал, не помогает...

Кто нибудь может сказать как такое может быть?


Не все GCC из 3.х стандартно поддерживали #pragma pack (если не ошибаюсь то только в 4 оно уже стандартно поддерживается)
попробуйте

typedef struct {
....
} param __attribute__((aligned (2)));
Go to the top of the page
 
+Quote Post
etoja
сообщение May 12 2008, 13:17
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 121
Регистрация: 14-01-05
Из: Москва
Пользователь №: 1 952



В ГНУ компиляторе #pragma pack(1) не работает.
Используйте конструкцию вида:

struct foo
{
char a;
int x[2] __attribute__ ((packed));
};

Это можно найти в хелпе к Rowley Crosstudio 1.4 build5.

А лучше используйте компилятор GreenHills Multi2000 for ARM. Там работает #pragma pack(1) для упаковки структур и можно располагать данные с границы байта, двух байт, четырёх байт.
Go to the top of the page
 
+Quote Post
alexander55
сообщение May 12 2008, 13:19
Сообщение #5


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(Andy Sm. @ May 12 2008, 16:49) *
Кто нибудь может сказать как такое может быть?

Добавьте еще один
unsigned short DOPOLNENIE;
и убедитесь, что осталось 96.
Go to the top of the page
 
+Quote Post
Andy Sm.
сообщение May 12 2008, 13:47
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 27-11-07
Пользователь №: 32 718



В общем, __attribute__ в разных вариациях не помогает.
Добавление ещё одного short_а не изменяет размер структуры, чего и следовало ожидать.
Это конечно самый короткий путь, но он меня почему то не радует хотя и надежен.
Прочитал тут на каком то форуме буржуйском что пустышка может и не в конце структуры оказаться...

Так что наверное придется компилять новый toolchain =( с более свежим gcc... хотя есть подозрение что это именно ARM_овский GCC такой.
Go to the top of the page
 
+Quote Post
r301
сообщение May 12 2008, 14:47
Сообщение #7





Группа: Участник
Сообщений: 13
Регистрация: 20-10-07
Пользователь №: 31 533



попробуйте делать typedef отдельно от packed. Проверил на gcc version 3.3.1, sizeof(param) дает 94

Код
struct param_t
{
unsigned short Version;
unsigned short Hi_Addr;
unsigned short Lo_Addr;
unsigned short CtlReg;
unsigned short H_size;
unsigned short V_size;
unsigned short AccBin;
unsigned short XDelay;
unsigned short CCDTemp;
unsigned short GainDark;
unsigned short Period;
unsigned short Tint;
unsigned short DualRatio;
unsigned short FIFOState;
unsigned short InfoReg;
unsigned short Data[32];
} __attribute__((packed));

typedef struct param_t param;
Go to the top of the page
 
+Quote Post
sergeeff
сообщение May 12 2008, 19:42
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Тут большой вопрос, что такое "правильно" под виндой? Для x86 процессоров почти все равно, как данные упакованы. Для ARM принципиально важно, чтобы переменные лежали максимально выравнеными на границу слова (т.е. 32 бит). Вопрос чего ты желаешь добиться? Сохранения структуры при ее сериализации и передачи через некоторый канал связи на другую платформу или просто хочу, чтоб было 94 байта.
Go to the top of the page
 
+Quote Post
VAI
сообщение May 13 2008, 03:11
Сообщение #9


Профессионал
*****

Группа: Модераторы
Сообщений: 1 120
Регистрация: 17-06-04
Пользователь №: 37



Цитата
Тут большой вопрос, что такое "правильно"

Правильно выставлять одинаковое выравнивание и для винды и для АРМ.
Приоритет лучше сделать у девайса, а в винде ставить такое-же выравнивание, тогда проблем не будет.


--------------------
Если зайца бить, его можно и спички научить зажигать
Сколько дурака не бей - умнее не будет. Зато опытнее
Go to the top of the page
 
+Quote Post
alexander55
сообщение May 13 2008, 04:30
Сообщение #10


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(sergeeff @ May 12 2008, 23:42) *
Сохранения структуры при ее сериализации и передачи через некоторый канал связи на другую платформу ...

Еще, наверное, хочется не передавать лишнию информацию по каналам связи. Здесь 2%, а м.б. намного больше.
Как вариант решения проблемы.
Для этого случая надо иметь отдельную функцию, скажем, sizeof_m(). Написать ее для данного конкретного случая не составит труда.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение May 13 2008, 08:42
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Так значит вопрос состоит все таки в том, чтобы добиться одинаковой упаковки структур на разных платформах, а не в "странных" sizeof?
Тогда так и надо формулировать коллегам вопрос. А sizeof - он и в Африке sizeof - средство контроля за размерами и не более.
Go to the top of the page
 
+Quote Post
amw
сообщение May 13 2008, 09:29
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847



К примеру вот такая конструкция работает везде, и в Линукс и в Виндовс и на ПИКе и на АРМ.
Код
#ifdef __GNUC__
#define __PACKED_ATTR __attribute__ ((__packed__))
#else
#define __PACKED_ATTR   /*nothing*/
#ifndef __18CXX
#pragma pack(push, 1)
#endif
#endif /* __GNUC__ */

typedef struct __GENERIC_CMD
{
    unsigned char id;
    unsigned short status;
    unsigned char reserved[6];
} __PACKED_ATTR GENERIC_CMD, *PGENERIC_CMD;

#ifndef __GNUC__
#ifndef __18CXX
#pragma pack(pop)
#endif
#endif


--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть.
© Lewis Carroll. Alice's adventures in wonderland.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 13 2008, 11:05
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(amw @ May 13 2008, 12:29) *
К примеру вот такая конструкция работает везде, и в Линукс и в Виндовс и на ПИКе и на АРМ.
Вот еще один кросс-платформенный вариант: http://electronix.ru/forum/index.php?s=&am...st&p=268643


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
amw
сообщение May 13 2008, 18:29
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847



Цитата(Сергей Борщ @ May 13 2008, 14:05) *
Вот еще один кросс-платформенный вариант: http://electronix.ru/forum/index.php?s=&am...st&p=268643

Эту ветку не читал раньше, но использую похожый подход.
Имеется фыйл osdep.h в котором проводится анализ текущего компилятора, ОС и пр. Из него включаются платформенно-зависимые типа lnxdeps.h, windeps.h armdeps.h и пр.
Показанный по этой ссылке метод с макросом мне кажется еще более удобным.
Прилагаю пример таких файлов. Эти файлы размещаются в репозитарии в папке osdep smile.gif и потом нужно только #include <osdep/osdep.h> и все.
Если к этому добавить макрос (по ссылке поста) то очень даже красиво и просто.
Прикрепленные файлы
Прикрепленный файл  osdep.zip ( 3.36 килобайт ) Кол-во скачиваний: 48
 


--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть.
© Lewis Carroll. Alice's adventures in wonderland.
Go to the top of the page
 
+Quote Post
Andy Sm.
сообщение May 15 2008, 10:07
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 27-11-07
Пользователь №: 32 718



вообще говоря, вопрос был про то как сказать gcc конкретной версии что бы он не делал выравнивание. r301 за ответ огромное спасибо.

а как писать кросс-платформенно и прочее это уже не совсем по теме. =)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 08:43
Рейтинг@Mail.ru


Страница сгенерированна за 0.01513 секунд с 7
ELECTRONIX ©2004-2016