2010-10-11 8 views
7

Ich frage vielleicht eine dumme Frage, aber ich schaute auf die Wikipedia-Seite für RVO here und konnte nicht aufhören zu fragen, ob dieses Verhalten falsch ist. Ich habe es in meiner Maschine ausprobiert und RVO ist trotz Optimierungslevel voll eingeschlagen. Was ist, wenn es tatsächlich etwas gab BIG in einem Konstruktor? 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.Ist die Rückgabewertoptimierung (RVO) kein Fehler?

EDIT: -fno-elide-constructors scheint RVO zu stoppen. Aber die Frage bleibt.

EDIT2: Auf eine ernstere Notiz, wie viele Menschen 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 oder?

+1

persönlich weggelassen werden, ich denke, dass RVO ist eine Abscheulichkeit. –

+10

Können Sie einen brauchbaren Anwendungsfall für nicht-schädliche Nebenwirkungen in einem Kopierkonstruktor finden? Ich habe keine, keine Hand. Sie werden im Allgemeinen hinter den Kulissen genannt, und es ist wirklich leicht, einen Fehler zu machen, wenn man sich bestimmt, wann sie angerufen werden. Das ist für mich ein guter Grund, die Nebenwirkungen auszulassen. –

+1

Ich habe keinen Grund, Nebenwirkungen in einen Kopierkonstruktor zu legen. :) – nakiya

Antwort

20

Die Standard legt fest, dass Operationen mit Sorge ein Programm des beobachtbaren Zustand müssen entfernt werden nicht optimiert, Ausnahme Kopie Bau 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).

+0

Aus diesem Grund ist die Weitergabe von Werten besser? – nakiya

+0

Es ist ein Grund, warum Pass-by-Value * besser sein könnte *. Das ist auch kein universeller Ratschlag. Manchmal ermöglicht Pass-by-Value Optimierungen, die bei Referenzübergabe nicht möglich wären, in manchen Fällen jedoch auch langsamer. :) – jalf

+0

Außerdem dachte ich, dass boost :: shared_ptr von diesen beiden Funktionen für die Referenzzählung abhängig ist. Was passiert da? – nakiya

7

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 einige Dialekte.

13

Wie in den anderen Antworten gesagt, ist der Compiler erlaubt, auch nicht triviale Copy Konstruktoren und Zuweisungsoperatoren zu optimieren.

12.8.15

Wenn bestimmte Kriterien erfüllt sind, wird eine Implementierung erlaubt die Kopie Bau eines Klassenobjekts zu verzichten, auch wenn der Kopierkonstruktor und/oder Destruktor für das Objekt haben Nebenwirkungen. In solchen Fällen behandelt die Implementierung die Quelle und das Ziel der ausgelassenen Kopieroperation als einfach zwei verschiedene Arten, sich auf das gleiche Objekt zu beziehen, und die Zerstörung dieses Objekts tritt zu dem späteren Zeitpunkt auf, zu dem die beiden Objekte gewesen wären zerstört ohne die Optimierung. Diese Eliminierung von Kopiervorgängen ist in den folgenden Fällen zulässig (die zur Vermeidung mehrerer Kopien kombiniert werden können):

- In einer return-Anweisung in einer Funktion mit einem Klassenrückgabetyp, wenn der Ausdruck der Name eines Nicht-Ausdrucks ist -volatile automatisches Objekt mit dem gleichen cv-unqualifizierten Typ wie der Funktion Rückgabetyp kann der Kopiervorgang durch Aufbau das automatische Objekts direkt in die Funktion des Rückgabewert

weggelassen werden - wenn ein temporäres Klasse-Objekt, das nicht gewesen an eine Referenz gebunden (12.2) würde zu einem Klassenobjekt kopiert wird mit dem gleichen cv-unqualifizierten Typ, der Kopiervorgang kann durch den Bau das temporäre Objekts direkt in das Ziel der versäumten Kopie

+0

+1 für das Angebot, bitte auch einen Link zu einer Kopie des Standards zur Verifizierung –

+1

@Matt: Das würde es zu einem Verweis auf Referenz machen. Scientific Papers und Bücher erwähnen normalerweise nur BibTex oder den Namen eines Buches, ohne Amazon oder ISO zu erwähnen, wo Sie diese Titel bekommen können. Wie auch immer, für Ihre Bequemlichkeit ist der neueste Entwurf des Standards unter http://open-std.org frei verfügbar. –

+0

In der modernen Zeit des WWW würde ich nicht weniger als einen Hyperlink erwarten, der direkt auf diesen Absatz verweist. Zu meiner Verteidigung gibt der Autor dieser Antwort nicht einmal an, aus welchem ​​Standard, welchem ​​Jahr oder welcher Version er das herausgenommen hat. –