Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
En plus des déclarateurs pour les membres d’une structure ou d’une union, un déclarateur de structure peut également être un nombre spécifié de bits, appelé « champ de bits ». Sa longueur est séparée du déclarateur du nom du champ par un signe deux points. Un champ de bits est interprété comme un type intégral.
Syntaxe
struct-declarator :
declarator
type-specifier
declarator
opter:constant-expression
La valeur constant-expression spécifie la largeur du champ en bits. La valeur type-specifier pour declarator doit être unsigned int, signed intou int, et constant-expression doit être une valeur entière non négative. Si la valeur est zéro, la déclaration n’a aucun declarator. Les tableaux de champs de bits, pointeurs vers des champs de bits et fonctions qui retournent des champs de bits ne sont pas autorisés. Le declarator facultatif désigne le champ de bits. Les champs de bits peuvent uniquement être déclarés comme faisant partie d’une structure. L’opérateur address-of (&) ne peut pas être appliqué aux composants de champ de bits.
Les champs de bits sans nom ne peuvent pas être référencés et leur contenu lors de l’exécution est imprévisible. Ils peuvent être utilisés comme des champs « factices », à des fins d’alignement. Un champ de bits sans nom dont la largeur est spécifiée comme 0 garantit que le stockage pour le membre suivant dans struct-declaration-list démarre sur une limite int.
Le nombre de bits dans un champ de bits doit être inférieur ou égal à la taille du type sous-jacent. Par exemple, les deux instructions suivantes ne sont pas autorisées :
short a:17; /* Illegal! */
int long y:33; /* Illegal! */
Cet exemple définit un tableau de structures à deux dimensions nommé screen.
struct
{
unsigned short icon : 8;
unsigned short color : 4;
unsigned short underline : 1;
unsigned short blink : 1;
} screen[25][80];
Le tableau contient 2 000 éléments. Chaque élément est une structure individuelle qui contient quatre membres de champ de bits : icon, color, underline et blink. La taille de chaque structure est de 2 octets.
Les champs de bits ont la même sémantique que le type entier. Un champ de bits est utilisé dans les expressions exactement de la même façon qu’une variable du même type de base serait utilisée. Peu importe le nombre de bits dans le champ de bits.
Section spécifique à Microsoft
Les champs de bits définis comme int sont considérés comme signed. Une extension Microsoft de la norme ANSI C autorise les types char et long (signed et unsigned) pour les champs de bits. Sans champs de bits avec le type de base long, short ou char (signed ou unsigned) forcent l’alignement sur une limite appropriée pour le type de base.
Les champs de bits sont alloués dans un entier du bit de poids le plus faible au bit de poids le plus fort. Dans le code suivant
struct mybitfields
{
unsigned short a : 4;
unsigned short b : 5;
unsigned short c : 7;
} test;
int main( void )
{
test.a = 2;
test.b = 31;
test.c = 0;
return 0;
}
Les bits de test sont disposés comme suit :
00000001 11110010
cccccccb bbbbaaaa
Les processeurs de la gamme 8086 stockent l’octet faible des valeurs entières avant l’octet fort. L’entier 0x01F2 serait stocké en mémoire physique comme 0xF2 suivi de 0x01.
La norme ISO C99 permet à une implémentation de choisir si un champ de bits peut chevaucher deux instances de stockage. Envisagez cette structure qui stocke des champs de bits totalisant 64 bits :
struct
{
unsigned int first : 9;
unsigned int second : 7;
unsigned int may_straddle : 30;
unsigned int last : 18;
} tricky_bits;
Une implémentation C standard peut empaqueter ces champs de bits dans deux entiers 32 bits. Elle peut stocker tricky_bits.may_straddle à raison de 16 bits dans un entier 32 bits, et 14 bits dans l’entier 32 bits suivant. La convention ABI Windows empaquette les champs de bits dans des entiers de stockage uniques et ne chevauche pas les unités de stockage. Le compilateur Microsoft stocke chaque champ de bits dans l’exemple ci-dessus de façon à ce qu’il tienne dans un seul entier 32 bits. Dans ce cas, first et second sont stockés dans un entier, may_straddle dans un deuxième entier et last dans un troisième entier. L’opérateur sizeof retourne 12 sur une instance de tricky_bits. Pour plus d’informations, consultez Remplissage et alignement des membres de structure.
FIN de la section spécifique à Microsoft