2013-01-07 12 views
7
#include <stdint.h> 
#include <stdio.h> 

typedef union { 
    uint64_t u[2]; 
    struct { 
     uint64_t a:30; 
     uint64_t b:30; 
     uint64_t c:30; 
     uint64_t d:30; 
     uint64_t e:8; 
    }x; 
} mystruct; 

int main() 
{ 
    printf("Size %d\n", sizeof(mystruct)); 
} 

Próbuję skompilować go na maszynie 64-bitowej. Oczekiwana moc wyjściowa wynosiła 16, ale otrzymuję 24. Wiem, że pewne wyrównanie stało się tutaj, ale nie jestem pewien, dlaczego jako struktura x ma dokładnie 16 bajtów. Czy ktoś może to wyjaśnić. Dziękisizeof nie pokazuje oczekiwanego wyjścia

+2

używasz bitfields: K & R strona 150: *” Niemal wszystko na temat bitfieldów zależy od implementacji "*. Osobiście pominąłbym "Prawie". – cdarke

+2

@cdark mówią * prawie *, ponieważ reszta jest nieokreślona;) – ouah

Odpowiedz

6

Z C Standard:

(C99, 6.7.2.1p10) „[...] W przypadku niewystarczającej ilości miejsca pozostaje czy nieco pola, które nie pasuje umieszczana jest w następna jednostka lub nakładające się jednostki sąsiednie to zdefiniowane przez implementację. "

Więc w implementacji nie pokrywają: a i b członkowie są w jednym urządzeniu, c i d są w innym jednej jednostce i e jest w innym jednej jednostki: 8 + 8 + 8 = 24.

6

przypadku maszyny z 64-bitowego pola a i b zużywają o 60 bitów, jak pierwsza wartość 64 bitów w Struct c i d użytku 60 bitów następnej wartości 64-bitowej w struktury, a następnie Ze względu e ma 8 bitów, nie może zmieścić się w 4 bitach pozostałych po tej 64-bitowej wartości, więc potrzebna jest kolejna wartość 64-bitowa. Zatem 8x3 = 24 bajty.

3

Element pola bitowego nigdy nie będzie nakładał się na dwie "jednostki" pamięci (w twoim przypadku jednostka pamięci jest elementem 64-bitowym).

Poza faktem, że bitfield realizacja są kompilator zależne, nie ma wszelkie szanse, że struktura bitfield jest faktycznie zapisane w następujący sposób pamięć:

struct { 
    uint64_t a:30; 
    uint64_t b:30; 
    uint64_t :4; 
    uint64_t c:30; 
    uint64_t d:30; 
    uint64_t :4; 
    uint64_t e:8; 
    uint64_t :56; 
}x;