2015-07-17 20 views
5

Jeśli debuguję poniższy kod, to widzę, że wartość size wynosi 12 (zgodnie z oczekiwaniami).Problemy podczas czytania rozmiaru struktury

#include <cstdint> 

int main(int argc, char *argv[]) 
{ 
    typedef struct __attribute__((__packed__)) { int8_t value; } time; 

    typedef struct __attribute__((__packed__)) { 
     uint8_t msg[8]; 
//  time t1; 
     uint32_t count; 
    } theStruct; 

    theStruct s; 
    int size = sizeof(s); 

    return 0; 
} 

Co ciekawe, usuwając komentarz w „czasie t1;”, wartość size idzie do 16. Spodziewałem 13.

wiem (mniej lub bardziej), że to wynika z danych struktura historia opasania ...

Ale czy jest jakiś sposób na uniknięcie tego problemu? Co należy zrobić, aby przeczytać size = 13?

+4

w moim test (g ++ 4.8.4) Otrzymuję rozmiar "13" z usuniętym komentarzem. Czy jesteś pewien, że przetestowałeś go poprawnie? –

+0

Tak, wpisano poprawnie. Używam (Qt enviroment x86) MinGW 4.8.2 32 bit – KcFnMi

+0

Mogę odtworzyć wyniki @ EvanTeran. BTW, jaki jest twój język programowania? C lub C++? Jak wywołujesz kompilator? – 5gon12eder

Odpowiedz

4

Występują pewne problemy z emulacją MinGW z MSVC struct packing.

Obejście problemu to przekazanie do kompilatora flagi -mno-ms-bitfields; spowoduje to, że użyje on własnego algorytmu układu, zamiast próbować emulować MSVC.

Zobacz także Struct packing and alignment with mingw (ARM, ale może to być ten sam problem).

+1

To właśnie myślałem, że ma to związek z systemem operacyjnym, ponieważ w moim systemie Linux tak się nie stało. I właśnie dlatego [zasugerowałem, co jest w moim komentarzu] (http://stackoverflow.com/questions/31480287/troubles-while-reading-tct-sct-size?noredirect=1#comment50926597_31480287), które możesz dołączyć do tej odpowiedzi Jeśli lubisz. –

0

Jest to wyraźnie problem dostosowania, co oznacza, że ​​nie ma nic wspólnego z samym językiem, ale wszystko z podstawową platformą.

Jeśli platforma wie (lub myśli), że int32_t potrzebuje wyrównania 4, powinna po chwili dodać 3 bajty wypełnienia.

W każdym razie __attribute__((__packed__)) jest niestandardowym C i będzie interpretowany tylko przez gcc (*). Co gorsza, prowadzi to do nieprzenośnych programów: zgodnie z this answer na inne pytanie, spowodowałoby to błąd magistrali w architekturze Sparc z powodu niewspółosiowości int32_t.

wiem, że x86 (i pochodne) Architektura są obecnie najbardziej powszechne, ale inna architektura może nadal istnieć ...

(*) zgodnie z Visual C++ equivalent of GCC's __attribute__ ((__packed__)), odpowiednik MSVC jest #pragma pack(push, 1)

Powiązane problemy