Was ist Kopierentscheidung? Was ist (benannte) Rückgabewertoptimierung? Was implizieren sie?
In welchen Situationen können sie auftreten? Was sind Einschränkungen?
- Wenn Sie auf diese Frage verwiesen wurden, suchen Sie wahrscheinlich nach der Einführung .
- Eine technische Übersicht finden Sie in der Standardreferenz .
- Siehe häufige Fälle hier .
c++
optimization
c++-faq
return-value-optimization
copy-elision
Luchian Grigore
quelle
quelle
Antworten:
Einführung
Für einen technischen Überblick - springen Sie zu dieser Antwort .
In häufigen Fällen, in denen eine Kopierentfernung auftritt, fahren Sie mit dieser Antwort fort .
Copy Elision ist eine Optimierung, die von den meisten Compilern implementiert wird, um in bestimmten Situationen zusätzliche (möglicherweise teure) Kopien zu vermeiden. Dies macht eine Rückgabe nach Wert oder Wertübergabe in der Praxis möglich (Einschränkungen gelten).
Dies ist die einzige Form der Optimierung, bei der (ha!) Die Als-ob-Regel außer Kraft gesetzt wird. Die Kopierelision kann angewendet werden, auch wenn das Kopieren / Verschieben des Objekts Nebenwirkungen hat .
Das folgende Beispiel stammt aus Wikipedia :
Abhängig vom Compiler und den Einstellungen sind alle folgenden Ausgaben gültig :
Dies bedeutet auch, dass weniger Objekte erstellt werden können, sodass Sie sich auch nicht darauf verlassen können, dass eine bestimmte Anzahl von Destruktoren aufgerufen wird. Sie sollten keine kritische Logik in Kopier- / Verschiebungskonstruktoren oder Destruktoren haben, da Sie sich nicht darauf verlassen können, dass sie aufgerufen werden.
Wenn ein Aufruf eines Kopier- oder Verschiebungskonstruktors aufgehoben wird, muss dieser Konstruktor noch vorhanden und zugänglich sein. Dies stellt sicher, dass die Kopierelision das Kopieren von Objekten nicht zulässt, die normalerweise nicht kopierbar sind, z. B. weil sie einen privaten oder gelöschten Kopier- / Verschiebungskonstruktor haben.
C ++ 17 : Ab C ++ 17 ist Copy Elision garantiert, wenn ein Objekt direkt zurückgegeben wird:
quelle
Standardreferenz
Für eine weniger technische Ansicht und Einführung - fahren Sie mit dieser Antwort fort .
In häufigen Fällen, in denen eine Kopierentfernung auftritt, fahren Sie mit dieser Antwort fort .
Die Kopierentscheidung ist im Standard definiert in:
12.8 Kopieren und Verschieben von Klassenobjekten [class.copy]
wie
Das gegebene Beispiel ist:
und erklärt:
quelle
Gängige Formen der Kopierentfernung
Für einen technischen Überblick - springen Sie zu dieser Antwort .
Für eine weniger technische Ansicht und Einführung - fahren Sie mit dieser Antwort fort .
(Benannt) Die Rückgabewertoptimierung ist eine übliche Form der Kopierelision. Es bezieht sich auf die Situation, in der für ein Objekt, dessen Wert von einer Methode zurückgegeben wird, die Kopie entfernt wird. Das im Standard angegebene Beispiel veranschaulicht die Optimierung des benannten Rückgabewerts , da das Objekt benannt ist.
Regelmäßige Rückgabewertoptimierung tritt auf, wenn ein temporäres zurückgegeben wird:
Andere häufige Orte, an denen eine Kopierentfernung stattfindet, sind, wenn ein temporärer Wert übergeben wird :
oder wenn eine Ausnahme ausgelöst und vom Wert abgefangen wird :
Häufige Einschränkungen bei der Kopierentfernung sind:
Die meisten kommerziellen Compiler unterstützen Copy Elision und (N) RVO (abhängig von den Optimierungseinstellungen).
quelle
Copy Elision ist eine Compiler-Optimierungstechnik, die unnötiges Kopieren / Verschieben von Objekten verhindert.
Unter den folgenden Umständen darf ein Compiler Kopier- / Verschiebevorgänge weglassen und daher den zugehörigen Konstruktor nicht aufrufen:
Selbst wenn eine Kopierelision stattfindet und der Kopier- / Verschiebungskonstruktor nicht aufgerufen wird, muss er vorhanden und zugänglich sein (als ob überhaupt keine Optimierung stattgefunden hätte), da sonst das Programm fehlerhaft ist.
Sie sollten eine solche Kopierentfernung nur an Stellen zulassen, an denen das beobachtbare Verhalten Ihrer Software nicht beeinträchtigt wird. Die Kopierelision ist die einzige Form der Optimierung, bei der (dh Elide) beobachtbare Nebenwirkungen auftreten dürfen. Beispiel:
GCC bietet die
-fno-elide-constructors
Option, die Kopierelision zu deaktivieren. Wenn Sie eine mögliche Kopierentfernung vermeiden möchten, verwenden Sie-fno-elide-constructors
.Jetzt bieten fast alle Compiler eine Kopierelision an, wenn die Optimierung aktiviert ist (und wenn keine andere Option zum Deaktivieren aktiviert ist).
Fazit
Bei jeder Kopierentfernung werden eine Konstruktion und eine übereinstimmende Zerstörung der Kopie weggelassen, wodurch CPU-Zeit gespart wird und kein Objekt erstellt wird, wodurch Platz auf dem Stapelrahmen gespart wird.
quelle
ABC obj2(xyz123());
ist es NRVO oder RVO? wird es nicht temporäre Variable / Objekt wieABC xyz = "Stack Overflow";//RVO