2013-02-28 11 views
6

Próbuję użyć pól bitowych w C++, aby osiągnąć konkretny rozmiar klasy, ale z jakiegoś powodu jest większy niż się spodziewałem.Niewłaściwie ustawione atrybuty za pomocą pól bitowych w klasie C++

Problem polega na tym, że zgłaszana jest klasa o 32 bitach (4 bajty) (przekazana jako argument do sizeof) 5 bajtów. Przykład klasy poniżej:

typedef unsigned char u8; 
typedef unsigned int u32; 

class Test { 
    u8 four_bit_field : 4; 
    u8 eight_bit_field; 
    u32 twenty_bit_field : 20; 
}__attribute__((packed)); 

Jeżeli położenie four_bit_field i eight_bit_field są przełączane sizeof przywrócić prawidłową wielkość, 4 bajtów. Uważam, że jest to problem z przyporządkowaniem pamięci.

Ktoś zna przyczynę tego zachowania? I, co najważniejsze, jak mogę to naprawić, bez przełączania żadnych pozycji.

Odpowiedz

10

Pole pole bez liczby bitów jest wyrównane do następnej granicy bajtu, zamiast pakowania w inne pola bitowe. Tak więc pierwsze 4 bity zajmują bajt, drugie 8 bitów bajt, a ostatnie 20 bitów zajmuje 3 bajty, w sumie 5.

Jeśli dodasz bitowy rozmiar pola do 8-bitowego pola, to zadziała, zobacz http://ideone.com/Bexw6l

+0

To co myślałem, kiedy powiedziałem, jest to problem ułożeniu pamięci. Ale szukam rozwiązania tego problemu. – braunmagrin

+0

@braunmagrin, byłem zajęty testowaniem rozwiązania, zobacz moją edycję. –

+0

Przepraszam za pośpiech. Dzięki, że rozwiązany. – braunmagrin

2

Jest to rzeczywiście problem wyrównania. u8 eight_bit_field nie jest bitfield, to zwykły unsigned char (od nazwy), a char, signed char lub unsigned char jest naturalnie wyrównany na granicy bajtów.

można zatem skończyć z 4 bitów wyściółki pomiędzy four_bit_field i eight_bit_field4 bitów i wyściółka po twenty_bit_field; ten drugi może być ponownie użyty przez klasę pochodną, ​​ten pierwszy utracony na zawsze.

2

spróbuj wymusić dostosowanie do 1 bajta:

#pragma pack(1) 
class Test { 
    u8 four_bit_field : 4; 
    u8 eight_bit_field : 8; 
    u32 twenty_bit_field : 20; 
}; 
#pragma pack() 
+0

Dzięki, nie zdawałem sobie sprawy z dyrektyw '# pragma'. Zawsze się uczę ... – braunmagrin

Powiązane problemy