Union-erklärung



  • Hallo Leute,

    könnt ihr mir mal ein Union erklären, und ein einfaches Beispiel und anwendung zeigen?

    Versteh das nicht so genau, mit dem selber speicher etc!



  • Bei einer union sind alle Elemente AN DER SELBEN STELLE im Speicher angeordnet - also beeinflussen die sich gegenseitig:

    union test_un
    {
      int ival;
      char cval[sizeof(int)];
    };
    
    test_un test;
    test.ival=4711;
    for(int i=0;i<sizeof(int);++i)
      cout<<test.cval[i];
    

    Du greifst sowohl über ival als auch über cval auf die selben Daten zu, nur werden sie jeweils anders interpretiert (im ersten Fall als ganze Zahl (int), im zweiten Fall als Array von Zeichen (char[] - byteweise gelesen)).



  • @CStoll
    Warum zeigst du denn gleich, wie man eine Union im Allgemeinen nicht benutzen darf? Unions sind nicht für die Reinterpretierung von Werten gedacht. Dafür gibt es den reinterpret_cast. In einer Union ist zu jedem Zeitpunkt immer nur genau ein Element aktiv und es darf immer nur das Element gelesen werden, welches als letztes geschrieben wurde. Man darf aber nicht Element a schreiben und danach Element b lesen.

    Eine Union ist immer eine Platzoptimierung. D.h. prinzipiell könntest du überall dort wo man eine Union verwendet auch eine struct verwenden. Wenn deine struct-Elemente aber nun alle unabhängig voneinander sind und zu jeder Zeit immer nur genau ein Element gebraucht wird (aber nicht bei allen Objekten das gleiche), dann bietet sich häufig eine Union an.



  • Womit wir dann schon bei der falschen/missbräuchlichen Verwendung von unions angelangt wären. Nur auf das zuletzt zugewiesene Element einer unions darf lesend zugegriffen werden. Alles andere lässt der C++-Standard undefiniert. Eine union ist in erster Linie dazu da, um Speicher zu sparen. Das macht vor allem dann Sinn, wenn verschiedene Variablen sich gegenseitig ausschließen. Einfaches Beispiel dazu:

    struct X{
       int tag;
       union Data
       {
          int val1;
          double val2;
       };
    };
    

    Fiktiv angenommen kann val1 nur sinnvoll benutzt werden, wenn tag = 1 ist und val2 nur wenn tag = 2 ist. Da die Variablen val1 und val2 sich dann gegenseitig ausschließen und nicht vom Programm gleichzeitig benutzt werden, könnte man den Speicherplatz hier sparen, indem man beide an der selben Speicheradresse anfangen lässt. Bei heutigen Verhältnissen sind solche "Mikrooptimierungen" aber viel zu gefährlich, weil man viel Schabernack damit treiben kann.

    Wozu unions häufig vergewaltigt werden, ist type-punting. Dabei wird, wie der Name schon andeutet, das C++ Typssystem in die Tonne getreten und man behauptet, dass man es besser weiß als der Compiler, wie z.B. in dem Beispiel, dass CStoll gepostet hat. Die goldene Regel lautet hier: Don't lie to the compiler or it will get its revenge. Sprich, falls du dir gerade mit deinem Compiler und auf deiner Plattform 100% sicher bist, dass du das Speicherlayout der Daten kennst, kannst du theoretisch type-punting mit unions betreiben. Trotzdem ist und bleibt das extrem schmutzig, denn es verdeckt ohne jegliche Warnung etwas, wofür man eigentlich einen reinterpret_cast bräuchte. Dazu kommen noch spannende Alignment-Fehler, die bei falscher Benutzung auftreten können.

    Kurzum, sofern du nicht für embedded-Systeme mit sehr begrenzten Ressourcen entwickelst, lass die Finger weg von unions.

    Edit: Da war Hume mal wieder schneller 🤡 👍



  • ok, also brauch ich unions eigentlich nicht?
    weil dann hat sich auch die sache, mit dem anwendungsbeispiel erübrigt!



  • Da es hier gerade darum geht...

    Ich habe vor kurzem folgende Seite gefunden: http://www.it-academy.cc/content/article_browse.php?ID=1345
    Dort wird vorgestellt, wie man mit union die binäre Darstellung eines Zeichen erhalten kann.
    Ist das so in Ordnung bzw. sinnvoll?

    Nach eurer Erklärung ja eigentlich nicht, oder? Schließlich wird hier auch auf das Struct-Element zugegriffen, obwohl zuletzt das Zeichen-Element geschrieben wurde.



  • @predator:
    Den Beitrag in deinem Link halte ich für ziemlichen Käse. Das ist weder so wirklich in Ordnung, noch sinnvoll.


Anmelden zum Antworten