Перейти к содержанию
    

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

если написать sizeof (param) то под виндой вернёт 94 (что есть правильно).

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

GCC 3.3.5.

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

 

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

 

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

попробуйте

 

typedef struct {

....

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

struct foo

{

char a;

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

};

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

unsigned short DOPOLNENIE;

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сохранения структуры при ее сериализации и передачи через некоторый канал связи на другую платформу ...

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

#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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот еще один кросс-платформенный вариант: 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...