union: bytes ausgeben



  • langeweile schrieb:

    darthdespotism schrieb:

    Bei was für einer Code-Page?

    850

    ISO 8859-1 oder was? 850 sagt mir gar nichts.

    Bei unions darf man nur auf die Variable zugreifen die man zuletzt geschrieben hat.

    Wo steht's geschrieben?

    Das ist eine Empfehlung, wenn man nicht weiß was man macht ;), vll ist der Trick mit den Unions auch nicht ganz der Weg für sauberen Code, valides C++ ist es aber allemal.



  • Bei unions darf man nur auf die Variable zugreifen die man zuletzt geschrieben hat.

    Wo steht's geschrieben?[/quote]

    http://c-plusplus.net/forum/viewtopic-var-t-is-186331-and-postdays-is-0-and-postorder-is-asc-and-start-is-10.html



  • In der Registry (Win NT 5.1 SP2 de) steht nur Codepage 850...

    @spannend:
    Ich hätte das gerne als Zitat aus 'nem guten Buch, im Stroustrup find ich nix...

    Wie darf ich dann das hier verstehen? Irren sich etwa gleich mehrere Seiten?
    http://www.willemer.de/informatik/cpp/union.htm



  • spannend schrieb:

    Bei unions darf man nur auf die Variable zugreifen die man zuletzt geschrieben hat.

    Wo steht's geschrieben?

    http://c-plusplus.net/forum/viewtopic-var-t-is-186331-and-postdays-is-0-and-postorder-is-asc-and-start-is-10.html

    interessant.

    EDIT://

    langeweile schrieb:

    In der Registry (Win NT 5.1 SP2 de) steht nur Codepage 850...

    @spannend:
    Ich hätte das gerne als Zitat aus 'nem guten Buch, im Stroustrup find ich nix...

    http://de.wikipedia.org/wiki/Codepage_850

    Danach passt auch das Zeichen ...



  • EDIT://
    langeweile schrieb:
    In der Registry (Win NT 5.1 SP2 de) steht nur Codepage 850...

    @spannend:
    Ich hätte das gerne als Zitat aus 'nem guten Buch, im Stroustrup find ich nix...

    http://de.wikipedia.org/wiki/Codepage_850

    Danach passt auch das Zeichen ...

    Danke, aber ist das jetzt wirklich kein gültiges C++?



  • Nach HumeSikkins nicht, da ich den Standard nicht vorliegen habe kann ich da auch nicht mehr sagen


  • Mod

    Soweit ich es erkenne, ist das ein Problem von 3.10[basic.lval]/15, 9.2[class.mem]/17 und 9.5[class.union]/1 (und in unserem Falle noch 3.9[basic.types]/4)
    Zunächst einmal muss unser union ein POD sein - dann gilt wegen 9.2/17 für alle Member mem1,mem2: (void*)&mem1 == (void*)&mem2
    Nach 9.5/1 existiert immer nur der Wert des zuletzt geschriebenen Members. Das heißt aber nicht, dass der Zugriff auf ein anderes Member per se fehlerhaft ist, sondern eben nur, dass ein Zugriff über ein anderes Member eben auf den Wert des zuletzt geschriebenen Members ist (9.5/1 sagt etwas über die Existenz von Werten, nicht die Existenz von Membern an sich). Damit kommen wir dann zu 3.10/15, das uns sagt, wann ein solches Aliasing nicht zwingend unzulässig ist. In diesem Thread haben wir es mit der letzten Alternative "- a char or unsigned char type." zu tun und wegen 3.9/4 ist das nichts Anderes als der Zugriff auf die Objektrepräsentation des Wertes in i.
    In Shades Tutorial ist es etwas anders:

    union Test
        {
          int Int; //Annahme: sizeof(int) == 4
          struct
          {
            char byte1;
            char byte2;
            char byte3;
            char byte4;
          } Bytes;
          //char bytes[4]; //so könnte man es auch machen (statt der struct)
          //man würde dann statt t.Bytes.byte1 einfach t.bytes[0] schreiben - das ist geschmackssache.
        };
    

    Es ist tatsächlich keine Geschmackssache, denn byte2,byte3,byte4 sind nicht notwendig Alias auf die Objektrepräsentation von Int, selbst wenn sizeof(int)>=4 ist. Das Verhalten kann dann undefiniert sein, je nach Layout von Bytes, welches durch die Implementation definiert wird.
    Das ist aber ein alter Streit.



  • Super, da hab ich wieder was gelern 🙂


  • Mod

    Wobei anzumerken wäre, dass einige Compiler (zumindest gcc) Schwierigkeiten mit solchem Aliasing haben - obwohl dem Standard nicht zu entnehmen ist, dass hier

    union
    {
        int i;
        char x[sizeof(int)];
    };
    i = 5;
    cout << x[0];
    cout << reinterpret_cast<char&>(i);
    

    ein Unterschied besteht - in beiden Fällen kommen wir auf unterschiedlichem Wege zur Anwendung von 3.10/15 - ist letztere Variante gemeinhin sicherer vor amoklaufenden Optimierern und wohl auch etwas offensichtlicher in der Semantik.



  • Heißt das auf deutsch, dass mein Programm solange richtig ist, wie die union POD ist? (Sorry, aber diese Fachsprache ist ein bissl kompliziert... 😃 )


Anmelden zum Antworten