Ich stelle vielleicht eine dumme Frage, aber ich schaute auf die Wikipedia-Seite für RVO hier und konnte nicht aufhören mich zu fragen, ob Dieses Verhalten ist falsch. Ich habe es in meiner Maschine ausprobiert und RVO ist trotz Optimierungslevel voll eingeschlagen. Was passiert, wenn in einem Konstruktor tatsächlich etwas BIG passiert? Ich weiß es sollte nicht, aber was wäre wenn? Ich kann nicht verstehen, warum RVO immer noch passieren würde, wenn es im Konstruktor Nebenwirkungen gibt.
EDIT: -fno-elide-constructors
scheint RVO zu stoppen. Aber die Frage bleibt.
EDIT2: Auf eine ernstere Notiz, wie viele Leute wissen über so etwas? Es ist vielleicht im Standard, aber es ist immer noch ein wirklich hässliches Feature, wie ich es sehe. Zumindest sollten Compiler es standardmäßig deaktivieren und einen Switch für Leute bereitstellen, die davon wissen. :)
EDIT 3: Ich bestehe immer noch darauf, dass das wirklich schlecht ist. :). Ich glaube nicht, dass ich eine andere sprachliche Einschränkung kenne, die direkt gegen die Syntax der Sprache spricht. Alles andere wirft entweder Compiler- oder Linker-Fehler auf?
Der Standard schreibt vor, dass Vorgänge, die den beobachtbaren Zustand eines Programms betreffen nicht optimiert werden müssen, mit Ausnahme der Kopierkonstruktion unter bestimmten Umständen. Sie dürfen sich nicht darauf verlassen, dass Kopierkonstruktoren ausgeführt werden, selbst wenn sie Nebenwirkungen haben, die Sie erwarten (z. B. Konsolenausgabe).
Wie in den anderen Antworten gesagt, darf der Compiler auch nicht-triviale Copy-Konstruktoren und Zuweisungsoperatoren optimieren.
12.8.15
Wenn bestimmte Kriterien erfüllt sind, darf eine Implementierung die Kopierkonstruktion eines Klassenobjekts weglassen, sogar wenn der Kopierkonstruktor und / oder Destruktor für das Objekt haben Nebenwirkungen . In solchen Fällen behandelt die Implementierung die Quelle und Ziel der ausgelassenen Kopie Operation als einfach zwei verschiedene Möglichkeiten, auf das gleiche Objekt zu verweisen, und die Die Zerstörung dieses Objekts erfolgt zu einem späteren Zeitpunkt, wenn die beiden Objekte zerstört worden wären Optimierung. Diese Eliminierung von Kopiervorgängen ist unter den folgenden Umständen zulässig (die kombiniert werden können) um mehrere Kopien zu entfernen):
- in einer return-Anweisung in einer Funktion mit einem Klassenrückgabetyp, wenn der Ausdruck der Name eines nichtflüchtigen Objekts ist automatisches Objekt mit dem gleichen cv-unqualifizierten Typ wie der Rückgabetyp der Funktion, kann die Kopieroperation weggelassen werden indem Sie das automatische Objekt direkt in den Rückgabewert der Funktion einbauen
- wenn ein temporäres Klassenobjekt, das nicht an eine Referenz (12.2) gebunden wurde, in ein Klassenobjekt mit kopiert würde Derselbe cv-unqualifizierte Typ, die Kopieroperation kann weggelassen werden, indem das temporäre Objekt direkt in das Konstrukt erstellt wird das Ziel der ausgelassenen Kopie
Definieren Sie "falsch". Die Sprache C ++ erlaubt diese Art der Optimierung explizit, obwohl sie beobachtbar ist. Wenn das Verhalten Ihres Programms von einer bestimmten Implementierung abhängt, dann verwenden Sie leider nicht ISO C ++, sondern einen Dialekt.
Tags und Links c++ return-value-optimization