Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: sizeof() странно себя ведёт...
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Andy Sm.
Есть структурка.

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 пробовал, не помогает...

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

Может массив выровнял на гарницу 4 байт?
sff
Цитата(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)));
etoja
В ГНУ компиляторе #pragma pack(1) не работает.
Используйте конструкцию вида:

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

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

А лучше используйте компилятор GreenHills Multi2000 for ARM. Там работает #pragma pack(1) для упаковки структур и можно располагать данные с границы байта, двух байт, четырёх байт.
alexander55
Цитата(Andy Sm. @ May 12 2008, 16:49) *
Кто нибудь может сказать как такое может быть?

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

Так что наверное придется компилять новый toolchain =( с более свежим gcc... хотя есть подозрение что это именно ARM_овский GCC такой.
r301
попробуйте делать 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;
sergeeff
Тут большой вопрос, что такое "правильно" под виндой? Для x86 процессоров почти все равно, как данные упакованы. Для ARM принципиально важно, чтобы переменные лежали максимально выравнеными на границу слова (т.е. 32 бит). Вопрос чего ты желаешь добиться? Сохранения структуры при ее сериализации и передачи через некоторый канал связи на другую платформу или просто хочу, чтоб было 94 байта.
VAI
Цитата
Тут большой вопрос, что такое "правильно"

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

Еще, наверное, хочется не передавать лишнию информацию по каналам связи. Здесь 2%, а м.б. намного больше.
Как вариант решения проблемы.
Для этого случая надо иметь отдельную функцию, скажем, sizeof_m(). Написать ее для данного конкретного случая не составит труда.
sergeeff
Так значит вопрос состоит все таки в том, чтобы добиться одинаковой упаковки структур на разных платформах, а не в "странных" sizeof?
Тогда так и надо формулировать коллегам вопрос. А sizeof - он и в Африке sizeof - средство контроля за размерами и не более.
amw
К примеру вот такая конструкция работает везде, и в Линукс и в Виндовс и на ПИКе и на АРМ.
Код
#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
Сергей Борщ
Цитата(amw @ May 13 2008, 12:29) *
К примеру вот такая конструкция работает везде, и в Линукс и в Виндовс и на ПИКе и на АРМ.
Вот еще один кросс-платформенный вариант: http://electronix.ru/forum/index.php?s=&am...st&p=268643
amw
Цитата(Сергей Борщ @ 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> и все.
Если к этому добавить макрос (по ссылке поста) то очень даже красиво и просто.
Andy Sm.
вообще говоря, вопрос был про то как сказать gcc конкретной версии что бы он не делал выравнивание. r301 за ответ огромное спасибо.

а как писать кросс-платформенно и прочее это уже не совсем по теме. =)
ISK2010
Тоже столкнулся с выравниванием, которое в моей ситуации не просто не нужно, а даже вредит здоровью. Почитал тут немножко, и стал писать при каждом объявлении структуры __attribute__((packed)) .
А как сделать, чтобы, например, для всего файла *.h убрать выравнивание?

Спасибо, уже нашел: http://www.keil.com/support/docs/1689.htm
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.