Отговори на тема  [ 10 мнения ] 
__attribute__ ((__packed__)), GCC > 4.4.0 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение __attribute__ ((__packed__)), GCC > 4.4.0
Имам следният код:

Код:
#include <stdint.h>

#define DUMB_STATIC_ASSERT(test) typedef char assertion_on_mystruct[( !!(test) )*2-1 ]
#define ATTR_PACKED __attribute__ ((__packed__))
//#define ATTR_PACKED __attribute__ ((packed))

typedef union ATTR_PACKED tagMSG {
    struct ATTR_PACKED {
        uint32_t    ID;
        uint8_t     MSGTYPE;
        uint8_t     LEN;
        uint8_t     DATA[8];
    };
    struct ATTR_PACKED {
        uint8_t     ID_B0;
        uint8_t     ID_B1;
        uint8_t     ID_B2;
        uint8_t     ID_B3;
    };
    uint8_t     BUF[14];
} MSG;
DUMB_STATIC_ASSERT( sizeof(MSG) == 14 );

typedef struct ATTR_PACKED tagHID {
    //#pragma pack(1)
    uint8_t     cmd;
    uint8_t     nmsgs;
    uint32_t    stamp;
    uint8_t     TEC;
    uint8_t     REC;
    MSG  msg[4];
    //#pragma pack()
} HID;
DUMB_STATIC_ASSERT( sizeof(HID) == 64 );



При GCC 4.4.0, 32-bit MinGW, Win7 64-bit, sizeof е както следва:
sizeof(MSG)=14
sizeof(HID)=64

При GCC 4.9.1, 64-bit MinGW, Win7 64-bit и GCC 5.3.0, 32-bit MinGW, Win7 64-bit, съответно е:
sizeof(MSG)=14
sizeof(HID)=66

Поради каква причина GCC 4.9.x и 5.3.x не възприемат __attribute__ ((__packed__)) ??

_________________
Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....


Пет Сеп 16, 2016 4:34 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Вто Юли 31, 2007 2:55 pm
Мнения: 1792
Местоположение: София
Мнение Re: __attribute__ ((__packed__)), GCC > 4.4.0
Защо е с подчертавки самото "packed" ? И защо правилната версия е закоментирана?


Пет Сеп 16, 2016 6:26 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение Re: __attribute__ ((__packed__)), GCC > 4.4.0
woody написа:
Защо е с подчертавки самото "packed" ? И защо правилната версия е закоментирана?

И двете са "правилни", но не работят :-)
Засега зареших проблема като декларирах stamp като Reg32:
Код:
typedef union ATTR_PACKED tagReg32 {
    struct ATTR_PACKED {
        uint8_t   b0;   // LSB
        uint8_t   b1;
        uint8_t   b2;
        uint8_t   b3;   // MSB
    };
    struct ATTR_PACKED {
        uint16_t w0;// LSB
        uint16_t w1;// MSB
    };
    uint32_t dw;
} Reg32;

typedef struct ATTR_PACKED tagHID {
    //#pragma pack(1)
    uint8_t     cmd;
    uint8_t     nmsgs;
    Reg32     stamp;
    uint8_t     TEC;
    uint8_t     REC;
    MSG  msg[4];
    //#pragma pack()
} HID;


Сега sizeof(HID)=64, ама понеже трябва в много apps да променям структурата, ми
се ще да намеря причината защот новите GCC версии правят нещо различно от
примерно GCC 4.4.0

_________________
Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....


Пет Сеп 16, 2016 7:03 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Ное 21, 2004 11:31 pm
Мнения: 10088
Мнение Re: __attribute__ ((__packed__)), GCC > 4.4.0
общо-взето няма обяснение защо се случва, но някои версии наистина се държат като българска министърка...

опита ми показва, че членовете на структурата трябва да се подредят по големина - първи са най-големите, масиви и т.н., след това по-малките. каткто е при теб 8-8-32-8-8, някъде по средата се получава фалшиво алайнване в което няма логика, но е факт че получаваш 66 бита. особено често се случва на 64-бита компилатора. ако не ти трябват наистина 64, пусниго форс в 32, може и да ги събере правилно. пробвай и да ги преподредиш.


Пет Сеп 16, 2016 7:34 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение Re: __attribute__ ((__packed__)), GCC > 4.4.0
Е то хубаво ще ги преподреди, а ако става въпрос за предварително зададен патерн? Например хедър на някакъв блок или нещо в протокол?
Не може да не работи, нещо има гнило, това си е крайъгълен камък....

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Пет Сеп 16, 2016 8:01 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение Re: __attribute__ ((__packed__)), GCC > 4.4.0
Става дума структура, която се търкаля напред-назад между 64, 32, 16 и 8-битови процесори,
По принцип, работеше в GCC 4.4.0, интересно защо обаче в новите GCC са го прецакали. Или може би of C++11 ?
Няма значение колко битов е компилатора, и при 32, и при 64-бита дава един и същи резултат. Не съм още
погледнал дали и при микроконтролери няма да се получи изненада. То всъщност навсякъде при компилация
правя проверки колко ще ми върне sizeof() за конкретните структури, та ще ми изплюе warning ако се получи
разминаване :-)

_________________
Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....


Пет Сеп 16, 2016 8:07 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Ное 21, 2004 11:31 pm
Мнения: 10088
Мнение Re: __attribute__ ((__packed__)), GCC > 4.4.0
Цецо написа:
Не може да не работи, нещо има гнило, това си е крайъгълен камък....

така е, ама бозата е факт

виж този бъг

__attribute__((packed)) doesn't work on mingw32 targets since ms-bitfields became the default
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991

препоръчват да се компилира с -mno-ms-bitfields


Пет Сеп 16, 2016 8:26 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Вто Юли 31, 2007 2:55 pm
Мнения: 1792
Местоположение: София
Мнение Re: __attribute__ ((__packed__)), GCC > 4.4.0
GCC 4.9.2 на Линукс се държи нормално, та като нищо е mingw болежка.


Пет Сеп 16, 2016 8:45 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение Re: __attribute__ ((__packed__)), GCC > 4.4.0
Мда, това е, което ДедоБоре изрови, потвърдено с g++ -mno-ms-bitfields
MinGW 32/64-бита пакетира правилно променливите. Голямо Благодаря :-)

За тези, които използват Qt Creator, параметри към GCC се подават като в
*.pro файла се вмъкне QMAKE_CXXFLAGS += , например:
Код:
QMAKE_CXXFLAGS += -mno-ms-bitfields

_________________
Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....


Пет Сеп 16, 2016 9:39 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Ное 21, 2004 11:31 pm
Мнения: 10088
Мнение Re: __attribute__ ((__packed__)), GCC > 4.4.0
крушката си имала дръжка (от gcc internals)
Цитат:
Target Hook: bool TARGET_MS_BITFIELD_LAYOUT_P (const_tree record_type)

This target hook returns true if bit-fields in the given record_type are to be laid out following the rules of Microsoft Visual C/C++, namely:

(i) a bit-field won't share the same storage unit with the previous bit-field if their underlying types have different sizes, and the bit-field will be aligned to the highest alignment of the underlying types of itself and of the previous bit-field; (ii) a zero-sized bit-field will affect the alignment of the whole enclosing structure, even if it is unnamed; except that (iii) a zero-sized bit-field will be disregarded unless it follows another bit-field of nonzero size. If this hook returns true, other macros that control bit-field layout are ignored.

When a bit-field is inserted into a packed record, the whole size of the underlying type is used by one or more same-size adjacent bit-fields (that is, if its long:3, 32 bits is used in the record, and any additional adjacent long bit-fields are packed into the same chunk of 32 bits. However, if the size changes, a new field of that size is allocated). In an unpacked record, this is the same as using alignment, but not equivalent when packing.

If both MS bit-fields and ‘__attribute__((packed))’ are used, the latter will take precedence. If ‘__attribute__((packed))’ is used on a single field when MS bit-fields are in use, it will take precedence for that field, but the alignment of the rest of the structure may affect its placement.


така че очевидно случката може да се случи на всякакъв компилатор, просто зависи дали ms-bitfields е компилиран по дефолт.
до сега бях попадал на това явление и за мен имаше необичаен/стихиен характер.

все още не мога да преценя дали е бъг в плейсера или наистина е симулация на поведение на М$ компилатор. някой може ли да го пробва на вижуал С какво се получава?


Пет Сеп 16, 2016 11:02 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 10 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 1 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни