Anche se lo standard ANSI C specifica troppo poco su come i bitfield sono impacchettati per offrire un vantaggio significativo rispetto a "i compilatori possono impacchettare i bitfield come ritengono opportuno", tuttavia in molti casi proibisce ai compilatori di impacchettare le cose nel modo più efficiente.
In particolare, se una struttura contiene campi di bit, un compilatore è tenuto a memorizzarla come una struttura che contiene uno o più campi anonimi di un tipo di memorizzazione "normale" e quindi suddivide logicamente ciascuno di tali campi nelle sue parti di campo di bit costituenti. Quindi, dato:
unsigned char foo1: 3;
unsigned char foo2: 3;
unsigned char foo3: 3;
unsigned char foo4: 3;
unsigned char foo5: 3;
unsigned char foo6: 3;
unsigned char foo7: 3;
Se unsigned char
è di 8 bit, il compilatore dovrebbe allocare quattro campi di quel tipo e assegnare due campi di bit a tutti tranne uno (che sarebbe in un char
campo a sé stante). Se tutte le char
dichiarazioni fossero state sostituite con short
, ci sarebbero due campi di tipo short
, uno dei quali conterrebbe cinque campi di bit e l'altro conterrebbe i due rimanenti.
Su un processore senza limitazioni di allineamento, i dati potrebbero essere disposti in modo più efficiente utilizzando unsigned short
per i primi cinque campi e unsigned char
per gli ultimi due, memorizzando sette campi a tre bit in tre byte. Sebbene dovrebbe essere possibile memorizzare otto campi a tre bit in tre byte, un compilatore potrebbe consentirlo solo se esistesse un tipo numerico a tre byte che potrebbe essere utilizzato come tipo "campo esterno".
Personalmente, considero i bitfield definiti come fondamentalmente inutili. Se il codice deve lavorare con dati binari, dovrebbe definire esplicitamente le posizioni di archiviazione dei tipi effettivi e quindi utilizzare le macro o altri mezzi simili per accedere ai relativi bit. Sarebbe utile se C supportasse una sintassi come:
unsigned short f1;
unsigned char f2;
union foo1 = f1:0.3;
union foo2 = f1:3.3;
union foo3 = f1:6.3;
union foo4 = f1:9.3;
union foo5 = f1:12.3;
union foo6 = f2:0.3;
union foo7 = f2:3.3;
Una tale sintassi, se consentita, consentirebbe al codice di utilizzare i campi di bit in modo portabile, senza riguardo per le dimensioni delle parole o l'ordinamento dei byte (foo0 sarebbe nei tre bit meno significativi di f1, ma questi potrebbero essere memorizzati nel indirizzo inferiore o superiore). In assenza di tale caratteristica, tuttavia, le macro sono probabilmente l'unico modo portatile per operare con queste cose.