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 :

A quoi sert union ? [FAQ]


Sujet :

C++

  1. #1
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut A quoi sert union ?
    C'est une question qui peut paraitre bête ou simple, mais je ne vois pas dans quel cas il peut-être intéressant d'utiliser une union...

    Merci d'avance,
    Mindiell
    "Souvent, femme barrit" - Elephant man

  2. #2
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Finalement à pas grand'chose, car l'union est assez peu compatible avec le reste du système de type du C++ (boost::any y est beaucoup plus), et assez peu sûre à manipuler sans un minimum de rigueur.

    L'idée est d'optimiser l'espace mémoire quand, selon un discriminant défini en dehors de l'union, une valeur peut être d'un type ou un autre. Dans tout le code que j'ai pu écrire, je ne crois pas en avoir crée une seule.

    Certains (dont l'API Win32) utilisent une union pour faire des casts, mais cette utilisation n'a rien de portable, et n'est pas garantie en C++.
    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.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Points : 711
    Points
    711
    Par défaut
    Bonjour,
    Citation Envoyé par JolyLoic
    et assez peu sûre à manipuler sans un minimum de rigueur.
    C'est le cas pour tout programme : la rigueur est ... de rigueur. Sinon, autant aller planter des choux.
    Compilation sans erreur ne signifie pas programme sans erreur.
    L'indentation n'a pas été imaginée pour faire beau, mais pour faciliter la lecture des programmes.

  4. #4
    Membre éclairé Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Points : 871
    Points
    871
    Par défaut
    Citation Envoyé par JolyLoic
    Finalement à pas grand'chose, car l'union est assez peu compatible avec le reste du système de type du C++ (boost::any y est beaucoup plus), et assez peu sûre à manipuler sans un minimum de rigueur.

    L'idée est d'optimiser l'espace mémoire quand, selon un discriminant défini en dehors de l'union, une valeur peut être d'un type ou un autre. Dans tout le code que j'ai pu écrire, je ne crois pas en avoir crée une seule.

    Certains (dont l'API Win32) utilisent une union pour faire des casts, mais cette utilisation n'a rien de portable, et n'est pas garantie en C++.
    Il y a aussi boost::variant, qui est vraiment pas mal pour faire des types somme et types récursifs comme dans les langages comme OCaml.

    En quelques lignes tu te fabriques ton arbre binaire, quadtree...

    C'était plus facile à manipuler qu'une relation d'héritage explicite, quand tu veux rajouter des fonctions de manipulation.
    Pas besoin de modifier le code des classes.

    Ce qui est bien c'est que la vérification des types se fait à la compilation, puis plein d'autres avantages, tu es sûr de n'avoir que les types spécifiés lors de la définition.

  5. #5
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Points : 403
    Points
    403
    Par défaut
    Bonjour,

    Mindiell écrit :
    C'est une question qui peut paraitre bête ou simple, mais je ne vois pas dans quel cas il peut-être intéressant d'utiliser une union...
    Imbriquée dans une classe, l' union peut remplacer des constantes. L' union ne fait pas l' oignon, dans la mesure où ses valeurs de retour sont générallement des entiers, signés sur 16 ou 32 bits ...

    salut.

  6. #6
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Tu es sur de ne pas avoir lu enum au lieu d'union ?
    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.

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    union permet de créer un POD avec l'alignement et la taille maximale pour contenir n'importe laquelle de ses possibilitées, toutes des PODs.
    Chacune des possibilités consiste en un type et une variable. Ensuite, l'utilisation de cette variable avec l'opérateur. sert à indiquer quel type on manipule.
    C'est à toi de te débrouiller pour savoir quel est le type de ce que contient ton union.

    Exemple,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    union
    {
        int i,
        double d
    } u;
    peut contenir soit un int soit un double.
    Ensuite avec u.i = 3 je mets un entier dedans.
    avec u.d = 3.14 j'écrase cet entier et je mets un double.

    En C++ c'est relativement peu intéressant vu qu'on travaille pas qu'avec des PODs.
    On a alors des mécanismes similaires, comme boost.variant.
    Boost ftw

  8. #8
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Points : 403
    Points
    403
    Par défaut
    Bonjour,

    Merde je me suis trompé entre union et énumération.
    Selon le Pascal l' union n' est rien d' autre qu' une structure au sein de la structure.

    Mais le C et le C++ ( comme d' autres langages ) enveloppent ce concept de manière assez aisée.

    salut.

  9. #9
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Merci à tous,

    Merci loufoque, je sais comment ca s'utilise et à quoi ca doit servir, je parlais surtout de "à quoi ca vous sert" à vous car moi, je n'en voyais pas l'utilité.
    Mindiell
    "Souvent, femme barrit" - Elephant man

  10. #10
    Membre confirmé Avatar de toxcct
    Développeur informatique
    Inscrit en
    Juillet 2006
    Messages
    434
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2006
    Messages : 434
    Points : 511
    Points
    511
    Par défaut
    j'aimerais rajouter un exemple concret, quoi que tres précis, de l'utililsation d'une union.

    j'ai eu l'occasion, lorsque que je faisais de l'informatique industrielle, de devoir cabler des coupleurs electroniques pour parler avec certains composants electroniques.
    certains de ces coupleurs fonctionnent avec deux registres ; un registre en entrée, et un en sortie (un en lecture, et un en écriture).
    et parfois, il arrive que certains coupleurs aient ces deux registres à la meme adresse !
    voici un exemple d'union qui peut alors etre utilisé :
    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
    struct TRegistreIn {
        char bReady: 1;
        char unused: 3;
        char nVal:   4;
    };
     
    struct TRegistreOut {
        char bReady:         1;
        char bEmitSound:     1;
        char bTurnOffSystem: 1;
        char unused:         5;
    };
     
    union UCoupleur {
        TRegistreIn rIn;
        TRegistreOut rOut;
    };
    ainsi, on écrivait dans rOut, et on lisait dans rIn... ca permet de manipuler les bits d'un meme octet (mais ca pourrait etre étendu a plus, bien sur) de plusieurs facons différentes.
    besoin de réponses ? demande a un pote

  11. #11
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par toxcct
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    union UCoupleur {
        TRegistreIn rIn;
        TRegistreOut rOut;
    };
    ainsi, on écrivait dans rOut, et on lisait dans rIn...
    C'est l'utilisation dont je parlais pour faire du cast, qui est un comportement non défini selon la standard, et qui peut très bien faire exploser le programme. A moins bien entendu que le compilateur utilisé garantisse spécifiquement le fonctionnement de ce cas, ce qui est possible pour un compilateur pour faire de l'embarqué où les développeurs ont l'habitude de faire des manipulations douteuses .
    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.

  12. #12
    Membre confirmé Avatar de toxcct
    Développeur informatique
    Inscrit en
    Juillet 2006
    Messages
    434
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2006
    Messages : 434
    Points : 511
    Points
    511
    Par défaut
    Citation Envoyé par JolyLoic
    C'est l'utilisation dont je parlais pour faire du cast.
    pas exactement, car ici, on ne travailler quasiment jamais avec un octet dans son intégralité.
    on accede plutot aux bits comme ceci par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    UCoupleur uc;
    uc.rOut.bReady = 1;
    uc.rOut.bEmitSound = 1;
    uc.rOut.bTurnOffSystem = 0;
     
    send();  //par exemple
     
    while (uc.rIn.bReady != 1) ; //boucle infinie, pour l'exemple
     
    int i = uc.rIn.nVal;
    besoin de réponses ? demande a un pote

  13. #13
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Je vois, je vois, mais pourquoi ne pas utiliser simplement rIn et rOut 2 variables octets séparés ? Ou même un seul octet tout court... ?
    Mindiell
    "Souvent, femme barrit" - Elephant man

  14. #14
    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
    On utilise un seul octet, mais on y accède par des champs de bits. C'es plus pratique, quoi...

    À noter que ce n'est absolument pas portable, vu que non seulement les unions ne le sont pas, mais en plus l'ordre des champs de bits n'est pas garanti par la norme. Naturellement, sur un compilateur donné, surtout pour de l'embarqué, ces détails peuvent être garantis par la documentation de la plate-forme...
    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.

  15. #15
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Oui, mais qu'est-ce qui empêcherais d'utiliser le même octet pour faire ca (vu que c'est ce qui se passe au final) ? A donner 2 noms différents ?

    Malgré tout, je comprends assez bien que ca reste peu usité, merci à tous
    Mindiell
    "Souvent, femme barrit" - Elephant man

  16. #16
    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
    En utilisant un simple octet, on ne pourrait pas y accéder par deux champs de bits différents (ou un octet et un champ de bits)...
    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.

  17. #17
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Ah, oui, ... pas faux ça. Merci pour l'explication
    Mindiell
    "Souvent, femme barrit" - Elephant man

Discussions similaires

  1. A quoi sert XML-Schema
    Par Community Management dans le forum Valider
    Réponses: 20
    Dernier message: 26/01/2009, 09h52
  2. à quoi sert le délestage?
    Par r0d dans le forum Mode d'emploi & aide aux nouveaux
    Réponses: 5
    Dernier message: 06/10/2004, 14h34
  3. a quoi sert le schema dans postgres ??
    Par champion dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 13/09/2004, 10h25
  4. [info] A quoi sert ImageObserver ?
    Par FrigoAcide dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 22/03/2004, 17h20

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