Jump to content

    

sizeof() странно себя ведёт...

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

 

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

 

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

Share this post


Link to post
Share on other sites
Кто нибудь может сказать как такое может быть?

Может массив выровнял на гарницу 4 байт?

Share this post


Link to post
Share on other sites
если написать sizeof (param) то под виндой вернёт 94 (что есть правильно).

а под линухом на ARM_е 96 (что странно по меньшей мере)... =(

GCC 3.3.5.

#pragma pack пробовал, не помогает...

 

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

 

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

попробуйте

 

typedef struct {

....

} param __attribute__((aligned (2)));

Share this post


Link to post
Share on other sites

В ГНУ компиляторе #pragma pack(1) не работает.

Используйте конструкцию вида:

 

struct foo

{

char a;

int x[2] __attribute__ ((packed));

};

 

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

 

А лучше используйте компилятор GreenHills Multi2000 for ARM. Там работает #pragma pack(1) для упаковки структур и можно располагать данные с границы байта, двух байт, четырёх байт.

Share this post


Link to post
Share on other sites
Кто нибудь может сказать как такое может быть?

Добавьте еще один

unsigned short DOPOLNENIE;

и убедитесь, что осталось 96.

Share this post


Link to post
Share on other sites

В общем, __attribute__ в разных вариациях не помогает.

Добавление ещё одного short_а не изменяет размер структуры, чего и следовало ожидать.

Это конечно самый короткий путь, но он меня почему то не радует хотя и надежен.

Прочитал тут на каком то форуме буржуйском что пустышка может и не в конце структуры оказаться...

 

Так что наверное придется компилять новый toolchain =( с более свежим gcc... хотя есть подозрение что это именно ARM_овский GCC такой.

Share this post


Link to post
Share on other sites

попробуйте делать 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;

Share this post


Link to post
Share on other sites

Тут большой вопрос, что такое "правильно" под виндой? Для x86 процессоров почти все равно, как данные упакованы. Для ARM принципиально важно, чтобы переменные лежали максимально выравнеными на границу слова (т.е. 32 бит). Вопрос чего ты желаешь добиться? Сохранения структуры при ее сериализации и передачи через некоторый канал связи на другую платформу или просто хочу, чтоб было 94 байта.

Share this post


Link to post
Share on other sites
Тут большой вопрос, что такое "правильно"

Правильно выставлять одинаковое выравнивание и для винды и для АРМ.

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

Share this post


Link to post
Share on other sites
Сохранения структуры при ее сериализации и передачи через некоторый канал связи на другую платформу ...

Еще, наверное, хочется не передавать лишнию информацию по каналам связи. Здесь 2%, а м.б. намного больше.

Как вариант решения проблемы.

Для этого случая надо иметь отдельную функцию, скажем, sizeof_m(). Написать ее для данного конкретного случая не составит труда.

Share this post


Link to post
Share on other sites

Так значит вопрос состоит все таки в том, чтобы добиться одинаковой упаковки структур на разных платформах, а не в "странных" sizeof?

Тогда так и надо формулировать коллегам вопрос. А sizeof - он и в Африке sizeof - средство контроля за размерами и не более.

Share this post


Link to post
Share on other sites

К примеру вот такая конструкция работает везде, и в Линукс и в Виндовс и на ПИКе и на АРМ.

#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

Share this post


Link to post
Share on other sites
К примеру вот такая конструкция работает везде, и в Линукс и в Виндовс и на ПИКе и на АРМ.
Вот еще один кросс-платформенный вариант: http://electronix.ru/forum/index.php?s=&am...st&p=268643

Share this post


Link to post
Share on other sites
Вот еще один кросс-платформенный вариант: http://electronix.ru/forum/index.php?s=&am...st&p=268643

Эту ветку не читал раньше, но использую похожый подход.

Имеется фыйл osdep.h в котором проводится анализ текущего компилятора, ОС и пр. Из него включаются платформенно-зависимые типа lnxdeps.h, windeps.h armdeps.h и пр.

Показанный по этой ссылке метод с макросом мне кажется еще более удобным.

Прилагаю пример таких файлов. Эти файлы размещаются в репозитарии в папке osdep :) и потом нужно только #include <osdep/osdep.h> и все.

Если к этому добавить макрос (по ссылке поста) то очень даже красиво и просто.

osdep.zip

Share this post


Link to post
Share on other sites

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

 

а как писать кросс-платформенно и прочее это уже не совсем по теме. =)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this