RVO aka copy elision
-
return in functions funktioniert ja ganz analog zum Aufruf von Funktionen und deren parameter Initialisierung. Angenommen ich habe jetzt keinerlei compiler Optimierungen, wie viele Kopien würden dann bei dem folgenden Code gemacht
class Foo{ }; Foo instance(Foo f){ return f; } int main(){ Foo foo; Foo f = instance(foo); }
pass-by-value beim funktionsaufruf erschafft ein lokales Foo Objekt f. Wenn das returned wird, wird ein weiteres anonymes Foo Objekt mit Copy Ctor erschaffen. Und dann bei der initialisierung von f mit dem return der funktion ein drittes oder ist das das vorherige?
Und wo käme hier RVO zum Einsatz?
-
Parameter sind niemals für NRVO verfügbar, was auch entsprechend im Standard vermerkt ist (http://eel.is/c++draft/class.copy#elision-1.1). Daher hätten wir eine Kopie des Arguments, und einen move des Parameters.
-
gelöscht. Ich habe auf irgendwas von SeppJ geantwortet, das nicht mehr da ist.
-
wob schrieb:
gelöscht. Ich habe auf irgendwas von SeppJ geantwortet, das nicht mehr da ist.
Ja, meine Antwort war weniger genau als Arcoths und hätte daher wohl nur verwirrt.
-
ja aber beim return, geschehen da ohne rvo zwei kopien? also wird einanonymes objekt erzeugt und das dann zum copy initialisieren des objektes verwendet,dass durch den Funktionsaufruf initialisiert werden soll?
-
Sewing schrieb:
ja aber beim return, geschehen da ohne rvo zwei kopien? also wird einanonymes objekt erzeugt und das dann zum copy initialisieren des objektes verwendet,dass durch den Funktionsaufruf initialisiert werden soll?
Ja, ein return ist eine potentielle Kopie und wenn mit dem Ergebnis davon dann wieder ein anderes Objekt Kopierinitialisiert wird, ist das eine weitere potentielle Kopie. RVO könnte potentiell beide vermeiden, außer dass hier Arcoths zitierte Regel greift, und daher nur eine der beiden Kopien vermieden werden kann.
Deswegen ist das auch so furchtbar wichtig. Du wirst feststellen, dass selbst nicht-optimeirende Compiler normalerweise RVO durchführen, außer du treibst es ihnen explizit aus.
-
Sewing schrieb:
ja aber beim return, geschehen da ohne rvo zwei kopien? also wird einanonymes objekt erzeugt und das dann zum copy initialisieren des objektes verwendet,dass durch den Funktionsaufruf initialisiert werden soll?
Die Optimierung, die hier greift, ist nicht RVO, sondern allgemein copy elision, welche für prvalues seit C++17 ein fester Bestandteil der Sprache ist, und damit zwangsläufig durchgeführt werden muss. Der Funktionsaufruf ist ein prvalue, und initialisiert
f
unmittelbar.