aliasing und alignment



  • Auf Stack Overflow war irgendwo ein Beispiel, wo das ganze ohne lvalues gemacht wurde (in C) (Es ist ja nur für lvalues undefiniert). Würde das vlt in C++ auch gehen?



  • Wie willst du ohne lvalue auf ein Objekt zugreifen?



  • Stimmt, schreiben wird schwierig 🤡



  • lesen auch 😉



  • http://stackoverflow.com/a/4935669 schrieb:

    The following does not violate the aliasing rule, because it has no use of lvalues accessing different types anywhere

    template<typename B, typename A>
    B noalias_cast(A a) { 
      union N { 
        A a; 
        B b; 
        N(A a):a(a) { }
      };
      return N(a).b;
    }
    
    unsigned bar(float x) {
      return noalias_cast<unsigned>(x);
    }
    


  • Das ist laut Standard undefiniert:

    ISO/IEC 14882:2011 schrieb:

    In a union, at most one of the non-static data members can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time.



  • Can be stored. Aber da steht doch nichts von lesen, oder?



  • Aber was soll das bringen? Ist doch das gleiche wie memcpy, nur umständlicher.


  • Mod

    pyhax schrieb:

    http://stackoverflow.com/a/4935669 schrieb:

    The following does not violate the aliasing rule, because it has no use of lvalues accessing different types anywhere

    template<typename B, typename A>
    B noalias_cast(A a) { 
      union N { 
        A a; 
        B b; 
        N(A a):a(a) { }
      };
      return N(a).b;
    }
    
    unsigned bar(float x) {
      return noalias_cast<unsigned>(x);
    }
    

    Clever. Evtl. zu clever, weil zwar die Aliasiang-Regel nicht verletzt wird. Andererseits aber der Standard mm.W. nirgendwo sagt, was denn nun das Ergebnis dieses Memberzugriffes sein soll (also am Ende doch UB) - außer dem Wert, der entstände, wenn es ein lvalue-Ausdruck wäre, der zu einem rvalue konvertiert wird (was in Hinblick auf Alisiang eben gerade nicht zulässig ist).

    Die memcpy-Variante funktioniert wahrscheinlich auch nicht, jedenfalls scheint es in C recht explizit verboten zu sein (C99 6.5/6 6.5/7, den neuen Standard habe ich nicht).



  • pyhax schrieb:

    Can be stored. Aber da steht doch nichts von lesen, oder?

    Das impliziert imo dass alle anderen Werte außer dem aktiven ungültig sind.
    Nach dem alten C++ Standard wäre jeder Zugriff auf einen anderen Wert als den zuletzt beschriebenen explizit undefiniertes Verhalten.
    Die Passage wurde im neuen aber geändert und dort bin ich mir grad nicht ganz sicher, ob es nun undefiniertes Verhalten ist, oder ob einfach nur nirgendwo steht was genau rauskommen soll.
    Aber ob schon rein der Versuch darauf zuzugreifen oder einfach nur das Ergebnis undefiniert ist, ändert jetzt nix dran, dass man sowas nicht tun sollte.
    Falls der Standard da tatsächlich eine Grauzone hat, würd ich mich auf jeden Fall nicht drauf verlassen was da rauskommt, denn das wäre dann imo ganz klar ein Bug im Standard...


  • Mod

    dot schrieb:

    pyhax schrieb:

    Can be stored. Aber da steht doch nichts von lesen, oder?

    Das impliziert imo dass alle anderen Werte außer dem aktiven ungültig sind.
    Nach dem alten C++ Standard wäre jeder Zugriff auf einen anderen Wert als den zuletzt beschriebenen explizit undefiniertes Verhalten.

    Wo liest du das heraus?



  • camper schrieb:

    dot schrieb:

    pyhax schrieb:

    Can be stored. Aber da steht doch nichts von lesen, oder?

    Das impliziert imo dass alle anderen Werte außer dem aktiven ungültig sind.
    Nach dem alten C++ Standard wäre jeder Zugriff auf einen anderen Wert als den zuletzt beschriebenen explizit undefiniertes Verhalten.

    Wo liest du das heraus?

    Ich hab den alten Standard nichtmehr hier und kann grad kein entsprechendes Draft finden. Ich hab einfach irgendwo im Hinterkopf dass der sowas in Richtung "jeder Zugriff auf einen anderen als den zuletzt beschriebenen Member ist UB" gesagt hat. Mag natürlich sein dass ich mich irre...


Anmelden zum Antworten