Adresse von temporären Objekt?



  • Bei einer Klasse habe ich folgende Funktion:

    inline CvFont Style() const {
                return(m_font); //CvFont m_font;
            }
    

    Wird nun diese Funktion aufgerufen, erhalte ich folgende Warnung:

    Warnung: Adresse eines temporären Wertes wird ermittelt

    Erst wenn ich z.B. folgendes mache, geht's:

    inline CvFont& Style(){
                return(m_font); //CvFont m_font;
            }
    

    😕



  • Eher umgekehrt, aber ohne genaueres zu wissen (ist das in ner Klasse? ist da noch Code vor dem return?...) kann man wenig sagen.
    CvFont stammt von dir? Kann man da mal den Kopierkonstruktor sehen?



  • Ohne & wird das Objekt nach verlassen der Funktion bei einer Zuweisung kopiert,
    andernfalls gibst du eine Referenz auf einen Speicherbereich zurück,
    der nach verlassen gelöscht wird.
    Der Speicherbereich wird in beiden Fällen gelöscht, jedoch im Fall ohne &
    hast du ein neues Objekt, das du weiterverwenden kannst.



  • Ich möchte jetzt nichts Falsches behaupten, aber das const sollte
    in diesem Fall keinen Einfluß darauf haben.


  • Mod

    Hier ist weit und breit kein temporäres Objekt zu sehen, vermutlich erfolgt die Warnung beim Aufruf. Folglich wäre der betreffende Codeabschnitt zu betrachen.



  • Asus777 schrieb:

    Bei einer Klasse habe ich folgende Funktion:

    inline CvFont Style() const {
       return(m_font); //CvFont m_font;
     }
    

    Wird nun diese Funktion aufgerufen, erhalte ich folgende Warnung:

    Warnung: Adresse eines temporären Wertes wird ermittelt

    Ja wie rufst Du sie denn auf? Etwa so?

    CvFont* ptr = &obj.Style();
    

    Das wäre illegal. Aber Dein Compiler bietet vielleicht eine Erweiterung an, mit der dieser Unfug möglich wird.

    Asus777 schrieb:

    Erst wenn ich z.B. folgendes mache, geht's:

    inline CvFont& Style(){
        return(m_font); //CvFont m_font;  
      }
    

    😕

    Dann mach's doch so. Wenn der Aufrufer direkt Zugriff auf das m_font -Datenelement Deines Objekts haben will/soll, dann musst Du es so machen. Wenn Du nur den Wert bzw eine Kopie zurückgeben willst, musst Du das & weglassen. Dann liefert ein Aufruf dieser Funktion einen Wert bzw ein temporäres (kurzlebiges) Objekt (die Kopie), welches am Ende des vollständigen Ausdrucks, der den Funktionsaufruf enthält, wieder zerstört wird -- es sei denn, Du machst so etwas:

    CvFont const& cref = obj.Style();
    

    Hier tritt eine Sonderregel in Kraft.

    return ist auch keine funktion. Die Klammern kannst Du Dir sparen.

    kk



  • Was genau ist mit "(Note this only applies to stack-based references. It doesn’t work for references that are members of objects.)" gemeint?
    Ein Klassenobjekt kann ja auch am Stack erzeugt werden. Also meint er nur mit new erzeugte Objekte oder wirklich nur reine Variablen?



  • Fräge! schrieb:

    Was genau ist mit "(Note this only applies to stack-based references. It doesn’t work for references that are members of objects.)" gemeint?
    Ein Klassenobjekt kann ja auch am Stack erzeugt werden. Also meint er nur mit new erzeugte Objekte oder wirklich nur reine Variablen?

    Nur reine Variablen. Wäre auch etwas unglücklich wenn es mit meber-Referenzen mal funktioniert und mal nicht, je nachdem ob das Objekt auf dem Stack angelegt wird oder nicht. Zumal dann noch so späze dazukämen wie "ich bau mir ein genügend großes char-Array auf dem Stack und klopf da mit placement-new ein pseudo-nicht-stack-objekt rein das in wirklichkeit doch auf dem stack liegt" usw.



  • pumuckl schrieb:

    Zumal dann noch so späze dazukämen wie "ich bau mir ein genügend großes char-Array auf dem Stack und klopf da mit placement-new ein pseudo-nicht-stack-objekt rein das in wirklichkeit doch auf dem stack liegt"

    Tut mir leid für OffTopic, aber ich hatte in Erinnerung, dass das nicht ohne Weiteres möglich (im Sinne von definiertem Verhalten) ist. Zumindest meinte ich, man müsse das Alignment sicherstellen...


  • Mod

    Fräge! schrieb:

    Was genau ist mit "(Note this only applies to stack-based references. It doesn’t work for references that are members of objects.)" gemeint?
    Ein Klassenobjekt kann ja auch am Stack erzeugt werden. Also meint er nur mit new erzeugte Objekte oder wirklich nur reine Variablen?

    Gemeint ist der Fall, dass eine Memberreferenz an eine temporäres Objekt gebunden wird. Das kann nur in der Konstruktor-Initialiserungsliste passieren. In diesem Fall wird das temporäre Objekt nicht am Ende der Auswertung des Initialisierers zerstört (was ohne Bindung der Falle wäre), es lebt aber auch nicht bis zum Ende der Lebenszeit der Memberreferenz (die endet, wenn das Klassenobjekt zerstört wird).
    Statt dessen endet in diesem Fall die Lebenszeit des temporären Objektes beim Verlassen des Konstruktors, was zu früh sein dürfte, um irgendwie praktisch nützlich zu sein.

    struct foo {};
    struct bar
    {
        foo a;
        const foo& b;
        bar()
        : a(foo())  // temporary wird nach Initialisierung von a zerstört (wir unterstellen, dass keine copy elision sttatfindet)
        , b(foo()) 
        {
    ...
        } // temporary, das b initialisierte wird hier zerstört
    };
    

Anmelden zum Antworten