Namespaces
Variants

Bit-fields

From cppreference.net

Déclare un membre avec une largeur explicite, en bits. Les membres de champ de bits adjacents peuvent être compactés pour partager et chevaucher les octets individuels.

Une déclaration de champ de bits est une struct ou union déclaration de membre qui utilise le déclarateur suivant :

identifiant  (optionnel) : largeur
identifier - un nom du champ de bits qui est déclaré. Le nom est facultatif : les champs de bits sans nom introduisent le nombre spécifié de bits de remplissage
width - une expression constante entière avec une valeur supérieure ou égale à zéro et inférieure ou égale au nombre de bits dans le type sous-jacent. Lorsqu'elle est supérieure à zéro, c'est le nombre de bits que ce champ de bits occupera. La valeur zéro n'est autorisée que pour les champs de bits sans nom et a une signification spéciale : elle spécifie que le champ de bits suivant dans la définition de la classe commencera à la limite d'une unité d'allocation.

Table des matières

Explication

Les champs de bits ne peuvent avoir qu'un seul des types suivants (éventuellement const ou volatile qualifiés) :

  • unsigned int , pour les champs de bits non signés (par ex. unsigned int b : 3 ; a la plage [ 0 , 7 ] )
  • signed int , pour les champs de bits signés ( signed int b : 3 ; a la plage [ - 4 , 3 ] )
  • int , pour les champs de bits avec une signe définie par l'implémentation (notez que cela diffère de la signification du mot-clé int partout ailleurs, où il signifie "signed int"). Par exemple, int b : 3 ; peut avoir la plage de valeurs [ 0 , 7 ] ou [ - 4 , 3 ] .
  • _Bool , pour les champs de bits d'un bit (par ex. bool x : 1 ; ) a la plage [ 0 , 1 ] et les conversions implicites vers et depuis celui-ci suivent les règles de conversion booléenne.
(depuis C99)
  • les types entiers à précision de bits (par ex. _BitInt ( 5 ) : 4 ; a la plage [ - 8 , 7 ] et unsigned _BitInt ( 5 ) : 4 ; a la plage [ 0 , 15 ] ).
(depuis C23)

Des types supplémentaires définis par l'implémentation peuvent être acceptables. Il est également défini par l'implémentation si un champ de bits peut avoir un type atomic . (depuis C11) Le nombre de bits dans un champ de bits ( width ) détermine la limite de la plage de valeurs qu'il peut contenir :

#include <stdio.h>
struct S
{
    // champ non signé de trois bits,
    // les valeurs autorisées sont 0...7
    unsigned int b : 3;
};
int main(void)
{
    struct S s = {7};
    ++s.b; // dépassement non signé
    printf("%d\n", s.b); // sortie : 0
}

Plusieurs champs de bits adjacents sont autorisés à être (et sont généralement) regroupés ensemble :

#include <stdio.h>
struct S
{
    // occupera généralement 4 octets :
    // 5 bits : valeur de b1
    // 11 bits : non utilisés
    // 6 bits : valeur de b2
    // 2 bits : valeur de b3
    // 8 bits : non utilisés
    unsigned b1 : 5, : 11, b2 : 6, b3 : 2;
};
int main(void)
{
    printf("%zu\n", sizeof(struct S)); // affiche généralement 4
}

Le champ de bits sans nom spécial de width zéro interrompt le remplissage : il spécifie que le prochain champ de bits commence au début de la prochaine unité d'allocation :

#include <stdio.h>
struct S
{
    // occupera généralement 8 octets :
    // 5 bits : valeur de b1
    // 27 bits : inutilisés
    // 6 bits : valeur de b2
    // 15 bits : valeur de b3
    // 11 bits : inutilisés
    unsigned b1 : 5;
    unsigned    : 0; // commence un nouvel unsigned int
    unsigned b2 : 6;
    unsigned b3 : 15;
};
int main(void)
{
    printf("%zu\n", sizeof(struct S)); // affiche généralement 8
}

Parce que les champs de bits ne commencent pas nécessairement au début d'un octet, l'adresse d'un champ de bits ne peut pas être prise. Les pointeurs vers les champs de bits ne sont pas possibles. Les champs de bits ne peuvent pas être utilisés avec sizeof et _Alignas (depuis C11) (jusqu'à C23) alignas (depuis C23) (depuis C11) .

Notes

Les utilisations suivantes de champs de bits provoquent un comportement indéfini :

Les propriétés suivantes des champs de bits sont non spécifiées :

  • Alignement de l'unité d'allocation qui contient un champ de bits.

Les propriétés suivantes des champs de bits sont définies par l'implémentation :

  • Si les champs de bits de type int sont traités comme signés ou non signés.
  • Si les types autres que int , signed int , unsigned int , _Bool (depuis C99) , et (éventuellement unsigned ) _BitInt ( N ) (depuis C23) sont autorisés.
  • Si les types atomiques sont autorisés.
(depuis C11)
  • Si un champ de bits peut chevaucher une limite d'unité d'allocation.
  • L'ordre des champs de bits au sein d'une unité d'allocation (sur certaines plateformes, les champs de bits sont regroupés de gauche à droite, sur d'autres de droite à gauche).

Bien que le nombre de bits dans la représentation objet de _Bool soit au moins CHAR_BIT , la largeur du champ de bits de type _Bool ne peut pas être supérieure à 1 .

(depuis C99)

Dans le langage de programmation C++, la largeur d'un champ de bits peut dépasser la largeur du type sous-jacent (mais les bits supplémentaires sont des bits de remplissage), et les champs de bits de type int sont toujours signés.

Références

  • Norme C23 (ISO/IEC 9899:2024):
  • 6.7.2.1 Spécificateurs de structure et d'union
  • Norme C17 (ISO/CEI 9899:2018) :
  • 6.7.2.1 Spécificateurs de structure et d'union
  • Norme C11 (ISO/CEI 9899:2011) :
  • 6.7.2.1 Spécificateurs de structure et d'union
  • Norme C99 (ISO/CEI 9899:1999) :
  • 6.7.2.1 Spécificateurs de structure et d'union
  • Norme C89/C90 (ISO/IEC 9899:1990) :
  • 3.5.2.1 Spécificateurs de structure et d'union

Voir aussi

Documentation C++ pour Bit-field