2013-02-28 9 views
6

Sto cercando di utilizzare campi di bit in C++ per ottenere una dimensione di classe specifica, ma per qualche motivo è più grande di quanto mi aspettassi.Attributi disallineati usando campi di bit in classe C++

Il problema è che una classe con 32 bit (4 byte) sta segnalando (quando è passata come argomento a sizeof) 5 byte. Esempio classe sotto:

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)); 

Se le four_bit_field e eight_bit_field posizioni sono commutati, sizeof ritorno delle dimensioni appropriate, 4 byte. Credo che sia probabilmente un problema di allineamento della memoria.

Quindi qualcuno conosce il motivo di questo comportamento? E, soprattutto, come posso risolvere questo, senza cambiare alcuna posizione.

risposta

10

Il campo u8 senza un numero di bit viene allineato al prossimo limite di byte, anziché essere imballato con gli altri campi di bit. Così i tuoi primi 4 bit prendono un byte, i secondi 8 bit prendono un byte e gli ultimi 20 bit prendono 3 byte, per un totale di 5.

Se si aggiunge una dimensione di campo di bit al campo a 8 bit funzionerà, vedere http://ideone.com/Bexw6l

+0

Questo è quello che ho pensato quando ho detto che questo è un problema allineamento di memoria. Ma sto cercando una soluzione a questo problema. – braunmagrin

+0

@braunmagrin, ero impegnato a testare la soluzione, vedere la mia modifica. –

+0

Mi dispiace per la fretta. Grazie, ha risolto. – braunmagrin

2

È, infatti, un problema di allineamento. u8 eight_bit_field non è un bitfield, è un semplice unsigned char (dal nome) e uno char, signed char o unsigned char è naturalmente allineato su un limite di byte.

È pertanto finisce con 4 bit di riempimento tra four_bit_field e eight_bit_field e 4 bit di riempimento dopo twenty_bit_field; quest'ultimo eventualmente riutilizzabile da una classe derivata, il primo per sempre perso.

2

provare a forzare l'allineamento a 1 byte:

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

Grazie, non ero a conoscenza delle direttive '# pragma'. Sempre imparando ... – braunmagrin