Unions oder doch Bit-Shift und Bit-Operationen


  • Mod

    @Swordfish sagte in Unions oder doch Bit-Shift und Bit-Operationen:

    char unsigned 8 bit, 16 = 2 x 8. Passt wie Faust auf Auge.

    Was soll daran schlechtes Vorbild sein @SeppJ? Das ist doch genau das worum es geht, zu wissen was geht und was nicht geht.

    Dass das nur in diesem einen ganz speziellen Fall von 2x8Bit passt, wegen obskurer Sonderregeln, dass chars das ausnahmsweise dürfen? Der Lösungsweg wird beim kleinsten Anzeichen von Anforderungsänderung explodieren. Und zwar nicht auf die theoretische Art, wie dass der Union-Trick streng genommen nicht funktionieren könnte (aber funktionieren wird), sondern auf die böse Art, wo in der Compileranleitung explizit mit Beispiel davor gewarnt wird, dass das nicht funktionieren wird.



  • @SeppJ sagte in Unions oder doch Bit-Shift und Bit-Operationen:

    obskurer Sonderregeln

    Obskure Sonderregeln? Sorry, aber das ist schon immer so, war immer so und wird immer so sein daß chars, unsigned chars (und jetzt auch std::byte) aliasen dürfen. Ich würde eher im Hinblick auf Compilererweiterungen über "obskur" reden.

    @SeppJ sagte in Unions oder doch Bit-Shift und Bit-Operationen:

    Der Lösungsweg wird beim kleinsten Anzeichen von Anforderungsänderung explodieren.

    Ängerung der Anforderungen die es bei der Simulation eines 16 bit Prozessors nie nicht geben wird. (Hat man plötzlich eine 32- oder 64-bit CPU ist wohl die andere Registerbreite das was einem am wenigsten Kopfzerbrechen bereiten sollte.)

    @SeppJ
    @Swordfish sagte in Unions oder doch Bit-Shift und Bit-Operationen:

    aber wie gesagt, drop die Referenzen, schreib stattdessen vier Funktionen (die im Kompilat aufs selbe rauslaufen sollten) und Deine Wünsche sind erfüllt.

    @Swordfish sagte in Unions oder doch Bit-Shift und Bit-Operationen:

    um den Zugriff auf diese "Subregister" ging es ja garnicht vorrangig sondern um das setzen von Flags in einem Byte.


  • Mod

    Letztlich hast du aber eine direkt in die Sprache eingebaute Lösung, die praktisch immer funktioniert, und allgemein auf alles anwendbar ist, durch einen komplizierteren Eigenbau ersetzt, der in genau einem bestimmten Sonderszenario funktionieren wird. Und dieses Sonderszenario ist eines, wo die Unionlösung aus den gleichen Gründen (dass char-Zugriffe vom Optimierer potentiell als aliased angesehen werden) in jedem praktischen Szenario funktionieren wird. Wenn das kein schlechtes Vorbild ist, was dann?



  • @SeppJ Ich habe Dir doch schon gesagt daß sowas gerne im Compiler/IDE-Forum diskutiert werden kann. Vom Standard ist es nicht gedeckt. Mich verwundert auch ein wenig daß Du da offenbar Deine persönliche Meinung über Deine Aufgaben als Moderator stellst. Aber sei's drum.



  • C++ braucht dringend einen Standard, der definiert, welche Regeln man aus dem ersten Standard einhalten sollte! Und bei diesem neuen Standard bitte nicht den selben Fehler machen und direkt einen weiteren Standard definieren, der den zweiten Standard überwacht!


  • Mod

    @Swordfish sagte in Unions oder doch Bit-Shift und Bit-Operationen:

    @SeppJ Ich habe Dir doch schon gesagt daß sowas gerne im Compiler/IDE-Forum diskutiert werden kann. Vom Standard ist es nicht gedeckt. Mich verwundert auch ein wenig daß Du da offenbar Deine persönliche Meinung über Deine Aufgaben als Moderator stellst. Aber sei's drum.

    Du hast komische Ansichten darüber, wie ein Forum oder dessen Moderation funktioniert. Ich versuche dem Fragesteller bestmöglich zu helfen, und mit den anderen Diskussionsteilnehmern zu argumentieren. Denkst du nicht, dass ist das Ziel?

    In diesem Fall nimmt die Hilfe die Form einer Warnung an, dass man höllisch aufpassen muss, wenn man deinen Code übernehmen will. Mit einer Begründung, warum das so ist, und wieso ich ihn deswegen für ein schlechtes Vorbild halte.



  • @SeppJ sagte in Unions oder doch Bit-Shift und Bit-Operationen:

    Du hast komische Ansichten darüber, wie ein Forum oder dessen Moderation funktioniert.

    Das ist echt quatsch. Das du als 'Profi' aber den Tipp gibst, den Standard nur dann einzuhalten, wenn es einem gerade in den Kram passt, finde ich allerdings auch sehr befremdlich.



  • @SeppJ sagte in Unions oder doch Bit-Shift und Bit-Operationen:

    Du hast komische Ansichten darüber, wie ein Forum oder dessen Moderation funktioniert.

    Findest Du? Ich nicht. Stellt man diese Frage im Kontext vom Standard muss man sagen "Kannst Du machen, wundere Dich aber nicht wenns knallt.". Stellt man sie betreffend einer Erweiterung des Compilers XY kann man diese diskutieren. Mischen bringts nicht wirklich.



  • Ich find´s auch sehr seltsam, dass eigentlich immer am Standard festgehalten wird und plötzlich Compilererweiterungen empfohlen werden. Das Blöde an der Sache ist, dass das auch alle anderen Compiler berschwerdefrei fressen.


  • Mod

    Wir sind aber nicht hier, um den Standard zum heiligen Selbstzweck zu erheben. Beziehungsweise, ich (und einige andere) sind nicht deswegen hier, andere schon. Ich bin hier, um dem TE zu erklären, welche Lösungen in der Praxis warum empfehlenswert sind und welche nicht. Das ist nicht richtig oder falsch im Sinne von Forennutzung, sondern eine andere Art, Fragen zu beantworten. Der TE kann dann entscheiden, welche Lösung er bevorzugt. Für und wider der verschiedenen Ansätze wurden schließlich ausgiebig (und größtenteils auch sachlich) diskutiert.


  • Mod

    @DocShoe sagte in Unions oder doch Bit-Shift und Bit-Operationen:

    Ich find´s auch sehr seltsam, dass eigentlich immer am Standard festgehalten wird und plötzlich Compilererweiterungen empfohlen werden. Das Blöde an der Sache ist, dass das auch alle anderen Compiler berschwerdefrei fressen.

    Es gibt halt Sachen, die funktionieren praktisch immer, obwohl sie theoretisch nicht vom Standard gedeckt sind, sind aber gleichzeitg besser als strikt standardkonforme Lösungen, solange sie funktionieren. Bei wieder anderen Sachen hat es wiederum keine Nachteile, sich strikt standardkonform zu verhalten, daher wäre es dumm, es nicht zu tun. Und noch wieder andere Fälle sehen so aus, als wären sie besser als strikt standardkonforme Lösungen, aber in der Praxis funktionieren sie dann doch nicht.



  • @SeppJ sagte in Unions oder doch Bit-Shift und Bit-Operationen:

    Es gibt halt Sachen, die funktionieren praktisch immer, [...]

    Dann halte das eben wie Du willst. In einem Forum über Standard-C++ unions zum Type Punning zu empfehlen ist und bleibt ...

    @SeppJ sagte in Unions oder doch Bit-Shift und Bit-Operationen:

    (und größtenteils auch sachlich)

    Liest sich wie ein Vorwurf ich wäre unsachlich geworden. Eigentlich warte ich noch auf eine Entschuldigung Deinerseits.



  • Ab C++20 gibt es dafür dann std::bit_cast<To, From>.



  • Ach @Swordfish, du bist auch nicht immer der höflichste. (Und bevor mich jmd. darauf hinweist, ich auch nicht, weiss ich eh.)



  • @hustbaer Ich bin nur zu Neulingen unhöflich *scnr* *duck 'n run*



  • Ich fasse also mal zusammen.
    Mein Union Konstrukt ist nicht im Standard verankert, funktioniert aber trotzdem. Wenn sehr wahrscheinlich auch auf wackeligem Boden.

    @SeppJ sagte in Unions oder doch Bit-Shift und Bit-Operationen:

    Exakt. Die Garantie lautet salopp gesagt: "Du darfst das machen, aber zeig da bloß nicht mit 'nem Pointer drauf!"<

    dann dürfte aber dieses nicht funktionieren?

    union {
    uint16_t HL; // 16Bit Register-Paar HL
    struct {
    uint8_t L; // 8Bit Register L (lower 8Bit)
    uint8_t H; // 8Bit Register H (upper 8Bit)
    };
    } regHL;

    inc8Bit(regHL.L);

    wenn inc8Bit folgendermaßen mit Referenzparameter deklariert ist:

    void inc8Bit(uint8_t &value);

    denn das entspricht doch einem Pointer auf die Daten mit denen gearbeitet wird.

    Übrigens, das ganze ist ein 8Bit Prozessor, welcher 2 8Bit-Register im Bedarfsfall zu einem 16Bit-Register zusammenfassen kann.

    Sorry wenn die Codeformatierung fehlt. Schreibe aus der Arbeit, und im Browser hier funzt das nicht. 😫


  • Mod

    Anstatt den Paragraph mit eigenen Worten wiederzugeben, verlinke ich mal: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Type-punning
    Und dann doch noch einmal mit eigenen Worten: GCC erlaubt type punning via unions (also Zugriff auf Daten über einen anderen Datentyp, als sie geschrieben wurden), aber wenn man dann wieder über einen Zeiger auf diese Daten zugreift, hat man strict Aliasing verletzt (man greift auf die Daten mittels eines unpassenden Zeigers zu) und es könnte zu Problemen kommen.

    Dein Beispiel ist nicht vollständig genug, um zu sagen, ob strict Aliasing verletzt ist oder nicht. Wenn der letzte Schreibzugriff auf regHL auf das HL Feld ging, dann ist der Zugriff über inc8Bit illegal. Wenn der letzte Zugriff auf das Sub-struct ging, ist das in Ordnung.



  • @Netzschleicher sagte in Unions oder doch Bit-Shift und Bit-Operationen:

    dann dürfte aber dieses nicht funktionieren?

    Es darf alles funktionieren. Wenn der Standard sagt dass es nicht erlaubt ist, dann heisst das nur dass es nicht funktionieren muss. Es kann und darf aber zufällig doch gehen.

    Und ja, genau das von dir gezeigte Pattern ist in C++ ganz viel verboten (und auch in C und auch mit GCC). Weil eben Zugriff über Zeiger bzw. in deinem Fall halt über ne Referenz, was aber keinen Unterschied macht.



  • @hustbaer So ist es eben wenn man anfängt sich in den Fuß zu schießen. Zuerst mit der kleinkalibrigen Pistole ... und ehe man es merkt hat man eine Panzerfaust in der Hand ...



  • @Netzschleicher sagte in Unions oder doch Bit-Shift und Bit-Operationen:

    Sorry wenn die Codeformatierung fehlt. Schreibe aus der Arbeit, und im Browser hier funzt das nicht. 😫

    Du brauchst bloß drei Backticks (```) in eine Zeile vor und in eine Zeile nach Deinem Code schreiben.


Anmelden zum Antworten