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 :

typedef union en C++


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 45
    Par défaut typedef union en C++
    j'ai déclaré une structure; un registre 48 bit accessible chaque 6 bits comme suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    typedef struct reg48 {
    	unsigned int   b7:6 ,b6:6 ,b5:6 ,b4:6, b3:6, b2:6, b1:6, b0:6;
    } reg48;
     
    typedef union reg48_6 {
    	unsigned __int64 reg;// pour un accés à toute la valeurs
        reg48 b;
    }reg48_6;
    Et quand j'utilise ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    s.reg=0x5bdadd934fad;
    	cout<<hex<<s.reg<<"\n";
        cout<<hex<<s.b.b0<<" "<<s.b.b1<<" "<<s.b.b2<<" "<<s.b.b3<<" "<<s.b.b4<<" "<<s.b.b5;
        cout<<" "<<hex<<s.b.b6<<" "<<s.b.b7<<"\n";
     
    s.reg=0x5bda5d934fad;
    	cout<<hex<<s.reg<<"\n";
        cout<<hex<<s.b.b0<<" "<<s.b.b1<<" "<<s.b.b2<<" "<<s.b.b3<<" "<<s.b.b4<<" "<<s.b.b5;
        cout<<" "<<hex<<s.b.b6<<" "<<s.b.b7<<"\n";
    ça me donne la même décomposition pour les 2 DIFFERENTS NOMBRES!!, et elle est fausse!!!.
    j'ai affiché en binaire, j'ai remarqué que 2 bits aux milieu sont ignoré!!!

    je ne comprend pas pourquoi?
    COMMENT FAIRE UNE DéCOMPOSITION DE MON REGISTRE?

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    ça ressemble à une "erreur" de padding.
    Le padding par défaut est sûrement 8.

    #pragma pack(1) devrait corriger ça.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 45
    Par défaut
    ça veut dire quoi ça?
    Ou est ce que je le rajoute ce "#pragma pack(1)"?

    en plus,ma décomposition marche pour quelques nombres et non pour d'autres!!!!!!!

  4. #4
    Membre chevronné
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Par défaut
    Comme dit Bousk ça peut être un problème de padding.
    Et effectivement, en ce cas, rajouter #pragma pack(1) avant la definition de ta structure devrait aider.

    Sinon une autre solution pour décomposer ton registre consiste à faire des décalages (avec l'opérateur >>) et des masks (avec l'opérateur &).

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    D'après la norme, si tu écris dans un champ d'une union, tu n'as pas le droit de lire un autre champ.

    Après, certains compilateurs permettent de faire ce que tu fais (je crois que visual C++ le permet spécifiquement, du moins dans certaines situations), mais c'est du comportement non standard (qui plus est, ça risque de marcher pendant longtemps, puis de planter juste à la veille d'une livraison, parce qu'une autre modif ailleurs change la manière dont le compilateur optimise son code).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,

    Citation Envoyé par Bousk Voir le message
    #pragma pack(1) devrait corriger ça.
    Non. #pragma pack(1) ne concerne pas les champs de bits.

    Citation Envoyé par dida_plt Voir le message
    je ne comprend pas pourquoi?
    COMMENT FAIRE UNE DéCOMPOSITION DE MON REGISTRE?
    Avec Visual C++2010, tu dois déclarer ton champ de bits avec un type suffisant pour contenir l'ensemble de tes bits :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    typedef struct reg48 {
    	unsigned __int64   b7:6 ,b6:6 ,b5:6 ,b4:6, b3:6, b2:6, b1:6, b0:6;
    } reg48;
     
    typedef union reg48_6 {
       unsigned __int64 reg;// pour un accés à toute la valeurs
        reg48 b;
    }reg48_6;
    Mais cela ne fait que retarder d'éventuels problèmes...


    Outre la remarque de Loïc sur l'union, j'en rajoute une sur les champs de bits pour décourager leur utilisation.

    Lorsque tu as plusieurs champs de bits consécutifs (comme les tiens), l'organisation mémoire est la suivante :
    => L'ordre de rangement des bits (gauche à droite ou droite à gauche) est dépendant de l'implémentation
    => Le premier champ de bits est rangé dans un espace du type sous-jacent.
    => Ensuite le champ de bits suivant est ajouté à la suite s'il rentre en entier.
    => Lorsque le champ de bits suivant chevauche plusieurs espace du type sous-jacent, le comportement est dépendant du compilateur/plateforme cible qui peut soit mettre le nouveau champ entièrement dans un nouvel espace du type sous-jacent, soit répartir le champ de bit entre les deux éléments.
    Exemple en supposant un type sur un 1 octet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct expl
    {
       unsigned char champ1 : 6;
       unsigned char champ2 : 6;
    };
    On peut avoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
                 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
    champ1 :                                           X   X   X  X   X  X
    champ2 :                  X   X  X  X   X   X
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
                 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
    champ1 :                                           X   X   X  X   X  X
    champ2 :          X  X  X   X  X   X
    Ce qui constitue un problème évident à la portabilité de ton code...

    Je te conseille donc d'utiliser plutôt des fonctions de manipulation de bits pour les lire et les écrire à partir d'un type sous-jacent que tu maîtrise.
    Si tu peux mapper l'intégralité des bits dans un seul objet du type sous-jacent alors fais le (ce qui est le cas ici en changeant unsigned int en unsigned __int64 (*)). Sinon, préfères la manipulation de bits (décalages et masques).

    (*) ceci dit cela n'enlève rien au problème souligné par Loïc.

Discussions similaires

  1. comment est la memoire avec typedef union
    Par gronaze dans le forum C
    Réponses: 4
    Dernier message: 27/02/2007, 14h22
  2. UNION qui ne fonctionne pas
    Par r-zo dans le forum Langage SQL
    Réponses: 7
    Dernier message: 21/07/2003, 10h04
  3. Réponses: 6
    Dernier message: 26/01/2003, 13h45
  4. Créer une vue pour trier une requete UNION ?
    Par Etienne Bar dans le forum SQL
    Réponses: 3
    Dernier message: 03/01/2003, 20h22
  5. Sortir un typedef d'une classe
    Par Theophil dans le forum C++Builder
    Réponses: 13
    Dernier message: 03/07/2002, 17h21

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