union umgedrehte Elemente?



  • union A 
    { 
        struct 
        { 
            unsigned char b; 
            unsigned char g; 
            unsigned char r; 
            unsigned char a; 
        }; 
        int32_t color; 
    };
    

    Ist das jetzt portierbar?
    Meine Programme sollen ja überall laufen, ansonsten las ich das mit der union einfach weg, aber das wäre ja eigentlich schoin praktisch so. 🙄

    MfG MAV



  • portierbar ist alles, portabel ist das nicht. hoerst du nicht zu? nicht alle prozessoren haben die gleiche endianness.



  • Folglich sind Unions allgemein nicht portabel?



  • Mis2com schrieb:

    Folglich sind Unions allgemein nicht portabel?

    Wenn du darauf abzielst, über "Unterstrukturen" Teile einer großen Struktur (wie hier) zu manipulieren, nein. Wenn man unions nutzt um z.B. einen float und einen int irgendwo platzsparend zu speichern und man nie beides braucht, ja. Du könntest natürlich Dinge machen wie

    #ifdef BIG_ENDIAN
    // Struktur in Big-Endian
    #else
    // Struktur in Little-Endian
    #endif
    

    Dann ist mit einem define das plattformabhängig gesetzt werden muss portierbar 😉



  • das geht besser als das define selbst zu machen, und interessanterweise ist eine union die loesung:

    const union{
        unsigned short dummy;
        struct { unsigned char LITTLE, BIG; } IS;
    } ENDIAN = { 1 };
    

    und dann if(ENDIAN.IS.BIG) und so. ist jetzt ausm gedaechtnis, aber prinzipiell wars so.



  • <bösezunge> Immer schön davon ablenken, dass sein Problem niemals mit unions gelöst werden sollte, sehr schön ^^. Oh ich vergaß, bitweise Operatoren sind nur für Freaks da, deshalb verwenden wir jetzt alle unions und #ifdefs. </bösezunge>

    Sorry, ich konnte nich anders.



  • @ Mr N.

    😃 Nicht einem den Mund wässrig machen und dann schweigen, wenn du eine bessere Lösung für sein
    Problem hast, raus damit! 😕



  • @pad:

    Mr. N schrieb:

    und dann gibts ja noch die bitweisen operatoren:

    unsigned green(unsigned color) { return (color >> 8) & 0xFF; }
    

    so.



  • Klar, bitweise Operatoren sind hier die andere Lösung, ich dachte nur, es ginge mit unions noch einfacher, aber den gedanken verwerf ichd ann lieber wieder. 🙂
    Gut, danke für eure Hilfe.

    Ciao



  • Noch etwas Überzeugungsarbeit:

    Auch perfomance-mäßig spricht einiges für die Bitoperationen. Disassembliert ergeben die beiden Varianten (union und Bits):

    // Variante 1:
    // int green1 = a.g;
    :0040101D 8B4DF5                  mov ecx, dword ptr [ebp-0B]
    :00401020 81E1FF000000            and ecx, 000000FF
    :00401026 894DF4                  mov dword ptr [ebp-0C], ecx
    // Variante 2:
    // int green2 = (Color >> 8) & 0xFF;
    :00401033 33D2                    xor edx, edx
    :00401035 8A55FD                  mov dl, byte ptr [ebp-03]
    :00401038 8955F8                  mov dword ptr [ebp-08], edx
    

    Beides Mal wird von einer ungeraden Adresse gelesen. Bei Variante 1 werden aber 32 Bit gefordert, d.h. der Prozessor muss effektiv 64 Bit lesen (über die ungerade Adresse hinaus). Ich bin mir nicht ganz sicher, ob das bei Variante 2 auch so ist, oder ob die CPU merkt, dass nur das unterste Byte gefordert ist. Auf jeden Fall ein Pro für Variante 2.
    Noch eins:
    Der Opcode für das "and" in Variante 1 ist viel länger als der des "xor" in Variante 2. 🙂


Anmelden zum Antworten