IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Alignement d'une structure contenant des champs de bits


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité de passage
    Homme Profil pro
    ‫‬
    Inscrit en
    Août 2025
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : ‫‬

    Informations forums :
    Inscription : Août 2025
    Messages : 14
    Par défaut Alignement d'une structure contenant des champs de bits
    Bonjour,

    je souhaite comprendre la règle qui gère l'alignement des champs dans C Microsoft, j' ai trouvé une structure dont tous les membres sont champs de bits en total ils font 16 bits qui correspond à la taille d'un WORD.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct tag_struc{
        WORD    Champ1         :4;
        WORD    Champ2         :2;
        WORD    Champ3         :1; 
        ...
    } struc;
    Quelle est la taille de cette structure ?

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 495
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 495
    Par défaut
    Bonjour,

    Tant que le type reste identique d'un champ au suivant, c'est le même espace qui est progressivement rempli par les champs de bits successifs. En outre, on peut lire clairement ici : https://learn.microsoft.com/fr-fr/cp...?view=msvc-170

    Les champs de bits sont alloués dans un entier du bit de poids le plus faible au bit de poids le plus fort.
    Lorsque l'on change de type (à vérifier) ou lorsque que la largeur totale des champs de bits cumulés dépasse celle du type, un nouveau champ est alloué dans la structure et on recommence directement à partir du bit0 de ce nouveau champ. Les champs de bits ne sont jamais « à cheval » sur deux instances. J'imagine également que dans ce cas, les règles d'alignement (pragma pack) s'appliquent de façon ordinaire sur les plages réservées.

  3. #3
    Membre Expert
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    692
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 95
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 692
    Par défaut
    Salut,

    Citation Envoyé par Mist2024 Voir le message
    Quelle est la taille de cette structure ?
    Sa taille est définie par l'implémentation et ici elle a pour valeur sizeof(struct tag_struc).

  4. #4
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 773
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 773
    Par défaut
    Tiens bizarre personne n'a répondu sur la limitation des bits
    en gros Champ1 va occuper 4 bits (:4), Champ2 2 bits (:2) et Champ3 1 bit (:1)

    Ta structure n'est pas complète mais avec ses 3 champs, ta structure devrait faire 1 octet
    4 + 2 + 1 = 7, mais comme le dit @Obsidian, et d'après mes souvenirs la structure est toujours alignée sur 8 ou 16 bits.
    Par exemple si tu rajoutes 1 champs mais de + de 2 bits, le champ sera mis dans 1 autre octet et tu perdras 1 bit dans le premier octet.

  5. #5
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 648
    Par défaut
    Bonjour foetus,

    Citation Envoyé par foetus Voir le message
    ...4 + 2 + 1 = 7, mais comme le dit @Obsidian, et d'après mes souvenirs la structure est toujours alignée sur 8 ou 16 bits.
    Par exemple si tu rajoutes 1 champs mais de + de 2 bits, le champ sera mis dans 1 autre octet et tu perdras 1 bit dans le premier octet.
    C'est vrai sur une machine 8 bits mais pas sur une machine (et donc un compilateur) traitant des opérations de tailles supérieures. Aujourd'hui, avec une taille 64 bit, le chevauchement évoqué ne peut apparaître que sur des champs binaires de taille > 64. Comme la technique de récupération des valeurs est de type décalage et masquage, je suppose que SSE et autres SIMD ne sont pas mis à contribution (sinon on peut aller jusqu'à 512 bits avant rupture de champ). D'autant qu'il est vraisemblable que les champs d'un bit soient simplement gérés avec les opérations de bit test (BT, BTC, BTR et BTS).

    La taille de la structure est toujours arrondie à des multiples de 8, 16, 32 voire 64. Ce qui, combiné avec les alignements mémoires, peut se traduire par une consommation de nx32 voire nx64 bits. L'argument de l'économie de place n'est donc pas très fort.

    De même l'argument d'efficacité n'est pas moteur, car l'extraction, même si elle est masquée, prend plus de temps qu'accéder à un élément de base. L'exemple souvent donnée d'une date y:12, m:4, d:5 en est la démonstration. Les 21 bits impliquent un mot de 32 bits pour les accueillir soit la même place que uint16_t y, uint8_t m, uint8_t d qui présente une accessibilité directe (les champs restent adressables).

    Cependant les champs de bits sont particulièrement pratiques dans les protocoles de transmission car ils facilitent la sérialisation. Ils sont intéressants également dans les unions où ils peuvent donner un accès simple à des parties, par exemple aux couleurs sur 16 bits (G:6, R:5, B:5), tout en pouvant les manipuler comme uint16_t.

    De plus, les champs de bits peuvent servir à implémenter des set en C (certes limités).

    Salut
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  6. #6
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 418
    Par défaut
    Le tout est est de savoir si s'est optimisé automatiquent ou s'il faut donner un coup de pouce :

    Posons dans la structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    BYTE Idle : 7;
    BYTE Fct : 7;
    BYTE Status : 1;
    BYTE Data : 1;
    En tout nous avons 16 bits soit 2 octets.

    Malheureusement, le sizeof, dans ce cas présent, nous donne 3 octets !
    Par conséquent, rien ne semble optimisé !

    Donnons maintenant un petit coup de pouce :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    BYTE Idle : 7;
    BYTE Status : 1;
    BYTE Fct : 7;
    BYTE Data : 1;
    Le sizeof, donne cette fois ci, 2 octets !

    Mais le problème, c'est que je ne sais pas, à priori comment ça s'organise et on pourra toujours me garantir que ...
    Moi ... je traite les champs de bits manuellement pour être sûr de ce que je fais !

    Vous voulez un petit exemple :
    Le status byte d'un message MIDI : 1fffcccc (bit7 à 1, fff : 8 fonctions, cccc : 16 canaux)
    Dans ce domaine (musique) on a intérêt à rester dans les rails (et c'est vrai aussi pour mes locomotives) !

  7. #7
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 648
    Par défaut
    Bonjour,

    Il n'y a pas d'optimisation par réordonnancement et c'est une bonne chose si les données devaient être sérialisées.

    Il est vraisemblable que l'exemple donné par henderson soit vers un MPU 8 bits auquel cas 7711 et 1177 ne peuvent tenir sur 2 octet (et non pas 16 bits), mais que 1717, 7171, 1771 et 7117 le peuvent. On peut alors supposer que, dans ce cas de figure, un champ de plus de 8 bits poserait problème.
    Nom : Champ binaire 8b.png
Affichages : 140
Taille : 28,5 Ko
    Ce qu'il faudrait faire en 8 bits pour récupérer le champ à cheval

    Nom : Champ binaire 16b.png
Affichages : 138
Taille : 19,1 Ko
    Et pourquoi on préfère un format plus grand

    La règle est qu'il y a risque de fractionnement si la longueur totale des champs dépasse le plus grand format naturel entier de la cible.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

Discussions similaires

  1. Initialiser une structure contenant un tableau
    Par Muetdhiver dans le forum C
    Réponses: 4
    Dernier message: 13/10/2010, 18h46
  2. probleme avec une structure contenant un tableau
    Par bringer dans le forum Débuter
    Réponses: 8
    Dernier message: 31/05/2010, 16h18
  3. Réponses: 0
    Dernier message: 05/05/2010, 18h14
  4. Dupliquer une structure contenant des mutables
    Par bumbolol dans le forum Caml
    Réponses: 6
    Dernier message: 28/01/2009, 21h37
  5. Réponses: 2
    Dernier message: 07/11/2005, 18h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo