Même si la norme ANSI C spécifie trop peu sur la façon dont les champs de bits sont emballés pour offrir un avantage significatif par rapport aux "compilateurs sont autorisés à emballer les champs de bits comme bon leur semble", elle interdit néanmoins dans de nombreux cas aux compilateurs de conditionner les choses de la manière la plus efficace.
En particulier, si une structure contient des champs de bits, un compilateur doit la stocker sous la forme d'une structure qui contient un ou plusieurs champs anonymes d'un certain type de stockage «normal», puis subdiviser logiquement chacun de ces champs en ses parties de champ de bits constituantes. Ainsi, étant donné:
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;
Si unsigned char
est 8 bits, le compilateur devrait allouer quatre champs de ce type, et attribuer deux champs de bits à tous sauf un (ce qui serait dans un char
champ qui lui est propre). Si toutes les char
déclarations avaient été remplacées par short
, alors il y aurait deux champs de type short
, dont l'un contiendrait cinq champs de bits et l'autre contiendrait les deux autres.
Sur un processeur sans restrictions d'alignement, les données pourraient être présentées plus efficacement en utilisant unsigned short
pour les cinq premiers champs et unsigned char
pour les deux derniers, le stockage de sept champs de trois bits sur trois octets. Alors qu'il devrait être possible de stocker huit champs de trois bits sur trois octets, un compilateur ne pourrait permettre cela que s'il existait un type numérique de trois octets qui pourrait être utilisé comme type "champ externe".
Personnellement, je considère que les champs de bits tels que définis sont fondamentalement inutiles. Si le code doit fonctionner avec des données binaires, il doit définir explicitement les emplacements de stockage des types réels, puis utiliser des macros ou d'autres moyens similaires pour accéder à leurs bits. Il serait utile que C prenne en charge une syntaxe telle que:
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;
Une telle syntaxe, si elle était autorisée, permettrait au code d'utiliser des champs de bits de manière portable, sans tenir compte de la taille des mots ou de l'ordre des octets (foo0 serait dans les trois bits les moins significatifs de f1, mais ceux-ci pourraient être stockés au adresse inférieure ou supérieure). En l'absence d'une telle fonctionnalité, cependant, les macros sont probablement le seul moyen portable de fonctionner avec de telles choses.