Comment la taille d’une structure avec des champs de bits est-elle déterminée / mesurée?

#include  typedef struct size { unsigned int a:1; unsigned int b:31; unsigned int c:1; } mystruct; int main() { mystruct a; printf("%d", sizeof(a)); return 0; } 
  • Avec int b:31 , la sortie est 8.
  • Avec int b:1 , la sortie est 4.
  • Avec int b:32 , la sortie est 12.

Quelqu’un peut-il expliquer la raison?

Vous ne dites pas si vous savez ce que sont les champs de bits, mais je suppose que vous le savez.

Dans votre implémentation, évidemment unsigned int est un entier de 32 bits, occupant 4 octets. Cela représente les premier et deuxième exemples. Clairement, 3 champs totalisant 33 bits ne rentrent pas dans un seul unsigned int , d’où la nécessité de 8 octets dans le premier exemple. 3 champs de bits totalisant 3 bits entrent certainement dans un unsigned int , soit 4 octets seulement dans le deuxième exemple.

De plus, un champ de bits ne peut pas s’étendre sur plusieurs entiers. Ceci représente le troisième exemple. Je ne me souviens pas s’il s’agit d’une exigence de la norme ou simplement d’un détail de votre mise en œuvre. Quoi qu’il en soit, puisque b vaut 32 bits, il remplit lui-même un entier unsigned int , forçant ainsi a et c à occuper leur propre unsigned int , avant et après celui du milieu. Par conséquent, 12 octets.

C’est l’ordre qui compte. Le code suivant donnera Output: 8

 #include typedef struct size { unsigned int b:32; unsigned int a:1; unsigned int c:1; }mystruct; int main(int argc, char const *argv[]) { mystruct a; printf("\n %lu \n",sizeof(a)); return 0; } 

Unsigned int est un entier de 32 bits, occupant 4 octets. La mémoire est allouée de manière contiguë en mémoire.


Option 1:

 unsigned int a:1; // First 4 bytes are allocated unsigned int b:31; // Will get accomodated in the First 4 bytes unsigned int c:1; // Second 4 bytes are allocated 

Sortie: 8


Option 2:

 unsigned int a:1; // First 4 bytes are allocated unsigned int b:32; // Will NOT get accomodated in the First 4 bytes, Second 4 bytes are allocated unsigned int c:1; // Will NOT get accomodated in the Second 4 bytes, Third 4 bytes are allocated 

Sortie: 12


Option 3:

 unsigned int a:1; // First 4 bytes are allocated unsigned int b:1; // Will get accomodated in the First 4 bytes unsigned int c:1; // Will get accomodated in the First 4 bytes 

Sortie: 4


Option 4:

 unsigned int b:32; // First 4 bytes are allocated unsigned int a:1; // Second 4 bytes are allocated unsigned int c:1; // Will get accomodated in the Second 4 bytes 

Sortie: 8

Alignement

Le compilateur arrondit la taille de la structure à 32 bits, la taille de chaque object qu’il peut essayer de référencer à 32 bits, tout en préservant l’ordre des champs de bits.

Donc, si vous avez un élément 32 bits au milieu et des éléments 1 bit de chaque côté, il faut 3 mots de 32 bits à allouer et ainsi: 12 octets.

Dans les deux autres cas, il s’agit simplement de savoir dans quelle quantité d’objects 32 bits votre séquence de champs de bits peut être encapsulée, tout en préservant l’ordre des champs.

Selon la réponse de Steve Jessop, il suffit d’append quelques documents qui pourraient aider.

Un membre d’une structure ou d’une union peut avoir n’importe quel type d’object complet autre qu’un type modifié de manière variable. De plus, un membre peut être déclaré constitué d’un nombre spécifié de bits (y compris, le cas échéant, d’un bit de signe). Un tel membre est appelé un champ de bits, sa largeur est précédée de deux points

Une mise en œuvre peut allouer une unité de stockage adressable suffisamment grande pour contenir un champ de bits. S’il rest suffisamment d’espace, un champ de bits qui suit immédiatement un autre champ de bits dans une structure doit être compressé dans des bits adjacents de la même unité. Si l’espace restant est insuffisant, la définition d’un implémentation correspond à la définition d’un champ de bits non compatible. L’ordre d’atsortingbution des champs de bits au sein d’une unité (ordre élevé à ordre faible ou ordre faible à ordre élevé) est défini par la mise en œuvre. L’alignement de l’unité de stockage adressable n’est pas spécifié.

Dans un object de structure, les membres autres que les champs de bits et les unités dans lesquelles résident les champs de bits ont des adresses qui augmentent dans l’ordre dans lequel ils ont été déclarés . Un pointeur sur un object de structure, converti de manière appropriée, pointe vers son membre initial (ou si ce membre est un champ de bits, puis vers l’unité dans laquelle il réside), et inversement. Il peut y avoir un remplissage non nommé dans un object de structure, mais pas au début.

——ISO / IEC 9899: 201x 6.7.2.1