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

Langage C++ Discussion :

Bitfields & alignement


Sujet :

Langage C++

  1. #1
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut Bitfields & alignement
    Bonjour,

    Je rencontre des problèmes avec l'utilisation de bitfields. Sujet que je maîtrise mal.

    J'avais la structure suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // 2*32 bits partiellement remplis
    struct MaStruct
    {
    	unsigned long var01 :10;
    	unsigned long var02 : 3;
    	unsigned long var03 : 5;
    	unsigned long var04 : 5;
    	unsigned long var05 : 3;
    	unsigned long var06 : 3;
    	unsigned long var07 : 1;
    	unsigned long var08 : 1;
    	// on saute 1bit
    	// -------------------------
    	unsigned long var09 :17;
    	unsigned long var10 : 8;
    	// 7 derniers bits non utilisés
    };
    que j'ai transformée en :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // 64 bits totalement remplis
    struct MaStruct
    {
    	uint64_t var01 :10;
    	uint64_t var02 : 3;
    	uint64_t var03 : 5;
    	uint64_t var04 : 5;
    	uint64_t var05 : 3;
    	uint64_t var06 : 3;
    	uint64_t var07 : 1;
    	uint64_t var08 : 1;
    	uint64_t var09 :17;
    	uint64_t var10 : 8;
    	uint64_t var11 : 8;
    }};
    • j'ai rajouté un champ (var11)
    • j'ai changé le type de 32 en 64 bits
    • le cumul des bits fait 64 au lieu de 56


    La structure est initialement remplie par un reinterpret_cast faisant suite à une lecture de fichier.

    Il semble qu'à la suite de ma modif, les données que je récupère à partir du 32ème bit de la structure ne soient pas bonnes : à partir du champ var09, il y a un décalage d'1 bit (var09 et var10 ont une valeur 2 fois trop grande).
    Auriez-vous une idée ?

    PS : j'utilise VS2010 en 64 bits

  2. #2
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Lu,

    Il y a une chose que je ne comprends pas dans la première partie: les commentaires "on saute 1 bit" et "7 derniers bits non utilisés". On le saute quand le bit Oo ?
    J'ai l'impression qu'il manque un truc genre unsigned long:1; //ou 0.

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    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 630
    Points : 10 556
    Points
    10 556
    Par défaut
    @jo_link_noir
    Non je pense qu'il faut le voir comme cela
    Au début on a 2 paquets de var01 à var08 (p1) et var09-var10 (p2)
    Mais p1 ne représente que 31bits et p2 25bits.

    C'est pour cela que
    1. '"on saute 1bit" pour que p1 ait 32bits
    2. "7 derniers bits non utilisés" pour que p2 ait 32bits


    Mais justement oodini, a récupéré le bit "vacant" de p1 pour le mettre dans p2 (c'est var11: 7+1= 8)

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Ce fœtus est précoce et a déjà l'esprit bien affuté.

    C'est effectivement comme ça que ça se passe (ou devrait se passer).
    Sauf que, comme décrit, il y a un soucis...

  5. #5
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    Bonjour,

    Compiles tu en 64 bits? car si tu compile en 32 bits, ta structure sera alignée en bloc de 32 bits ce qui pourrait expliquer le décalage d'un bit supplémentaire au 31ème bit.
    Homer J. Simpson


  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Je compile en 64 bits. Hélas, c'est là qu'est l'os.

  7. #7
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    À mon avis, ce n’est pas un problème de compilation en 64 bits, mais de taille utilisée pour l’alignement.

    Tu remplaces des long (32 bits --> alignement sur 32 bits --> 1 bit est réservé avant var09 pour qu’il ne se retrouve pas à cheval entre 2 longs) par des uint64_t (64 bits --> pas de problème, pas de bit réservé).

    Si tu as vraiment besoin de uint64_t, tu peux, au choix :
    - réserver le 1 bit pour faire l’alignement entre var08 et var09
    - utiliser un uint32_t de longueur 0 avant var09 pour forcer l’alignement sur le prochain mot de 32 bits

  8. #8
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Justement, en utilisant un uint64_t, je pensais ne pas avoir à me soucier de l'alignement sur 32 bits.
    Je peux restreindre le champ que j'ai ajouté à 7 bits. Je vais faire ça, et revenir à des ulong.

  9. #9
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    J’ai l’impression que tu veux faire deux choses incompatibles entre elles :
    - décaler la structure pour avoir 8 bits à la fin (d’où le passage à des uint64_t pour régler la problématique d’alignement)
    - garder la compatibilité binaire, et donc var9 qui commence au deuxième mot

    Y a pas de magie. Tu auras soit l’un, soit l’autre, mais pas les deux.

  10. #10
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Oui, j'en étais également arrivé à cette conclusion peu flatteuse...

    Cela dit, j'aurais bien voulu en discuter avec le gars qui me donne les données à manger. parce que ç doit vouloir dire qu'avec l'ancien système, il décalait délibérément les données d'1 bit (ce n'est pas écrit en C/C++).

  11. #11
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Tu peux quand même résoudre le problème en dissociant la représentation mémoire de la sérialisation (à condition que tes 8 derniers bits ne soient là que pour toi et n’aient pas d’importance dans les données).

    Ça va ralentir (un peu) la lecture, mais bon…

  12. #12
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Ils ont de l'importance dans les données.

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    J'ai du mal à comprendre pourquoi simplement rajouter une variable de bourrage d'1 bit entre var08 et var09 ne marcherait pas.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Si tu ajoutes un bit de bourrage, tu arrives au total à 65 bits.

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ah oui, avec l'ajout de var11.
    Et bien, la seule façon que je vois de rester compatible sans dépasser la taille est de couper var11 en deux (placer un de ses bits entre var08 et var09).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Pentium] Optimisation - Alignement
    Par Blustuff dans le forum Assembleur
    Réponses: 58
    Dernier message: 05/04/2003, 17h01
  2. JBuilder7 & JTable Colonne alignement
    Par Tonton Luc dans le forum JBuilder
    Réponses: 5
    Dernier message: 06/11/2002, 17h32
  3. [Datareport] Alignement
    Par SpaceFrog dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 05/11/2002, 11h53
  4. [VB6] [Printer] Chiffres alignés à droite
    Par Laye dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 03/10/2002, 18h36

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