2010-02-24 6 views
5

Lesen this Wikipedia-Artikel von einem der repliers auf die folgende Frage hingewiesen:Führt "Rückgabewertoptimierung" zu undefiniertem Verhalten?

C++ Copy constructor, temporaries and copy semantics

ich auf dieser Linie kam

auf dem Compiler Je, und die Einstellungen des Compilers, das daraus resultierende Programm kann eine der folgenden Ausgaben anzeigen:

Ist dies nicht für undefiniertes Verhalten geeignet? Ich weiß, dass der Artikel Depending on the compiler and settings sagt, aber ich will das nur klären.

+3

Es ist eine Implementierung definiert, in der der Compiler-Implementierer das Verhalten dokumentieren muss, dann ist hier nicht spezifiziert, was bedeutet, dass der Compiler tun kann, was auch immer er will, solange das "beobachtbare Verhalten" gleich bleibt. Dann gibt es undefiniertes Verhalten, was bedeutet, dass Sie einen Zustand in dem Programm eingegeben haben, in dem die Ausführung nicht mehr definiert ist. RVO ist ein Fall, in dem sich beobachtbares Verhalten ändern kann. – GManNickG

Antwort

12

Nein, es ist kein undefiniertes Verhalten. Undefiniertes Verhalten hat eine spezifische Definition im Standard (meistens: "Verhalten, wie es bei Verwendung eines fehlerhaften Programmkonstrukts oder fehlerhafter Daten auftreten könnte, für die dieser Internationale Standard keine Anforderungen vorschreibt.") In diesem Fall ist das Verhalten nicht spezifiziert, aber nicht undefiniert.

Der Unterschied ist, dass jede Ausführung von etwas mit undefiniertem Verhalten das Verhalten Ihres Programms undefiniert macht (d. H. Alles kann passieren). Mit diesem bestimmten nicht spezifizierten Verhalten kann nur eines von zwei Dingen passieren: Entweder der Kopierkonstruktor wird ausgeführt oder nicht.

+0

Ich erinnere mich, dass ich ziemlich verwirrt war, als ich anfing zwischen: unbestimmt, unspezifiziert und implementierungsdefiniert. Sehr gute und prägnante Erklärung. –

2

Nein. Das Verhalten ist als einer der Ausgänge in der Liste definiert. Undefiniertes Verhalten beinhaltet Dämonen, die aus deiner Nase fliegen.

Siehe: Nasal Demons

1

undefined behavior von implementation defined behavior ganz anders ist, das ist das, was hier beteiligt ist.

+4

Es ist nicht wirklich die Implementierung definiert - das würde erfordern, dass die Implementierung dokumentiert, was passiert, was in diesem Fall nicht erforderlich ist. –

0

Hängt davon ab, was Sie mit undefiniert meinen. Ich glaube, was andere hier gesagt haben - nach der Definition des Standarddokuments. Aber ich weiß auch, wenn jemand sagt "Entweder das oder das, ich sage dir nicht, welches" ich es als undefiniertes Verhalten betrachte.

Es ist jedoch keine große Sache, da es nie einen Fehler verursachen sollte. Wenn Sie bestimmte Methoden definieren, müssen Sie sie nach bestimmten Konventionen definieren. Das ist eine Art impliziter Vertrag zwischen Ihnen, dem Compiler und den Personen, die Ihren Code verwenden und pflegen.

In diesem Fall, ob Sie ein Kopierkonstrukt usw. oder das optimierte Verhalten erhalten, wird erwartet, dass der Effekt derselbe ist - der Aufrufer erhält den gewünschten Wert. Wenn Ihr Kopierkonstruktor "Hello World!" oder hat andere unangemessene Nebeneffekte, es implementiert das erwartete Verhalten für einen Konstruktor nicht, so ist der Fehler für das Brechen des Vertrags Ihr.

+0

+1 für die Aussagen über die _Seiteffekte_, die aufgrund dieser Optimierung stillschweigend ausgeführt werden können :) Wenn es sich um eine Druckanweisung handelt, auf die Sie im Terminal eifrig achten, können Sie sie dennoch erfassen; während etwas stilleres, sagen wir, eine Nachricht an ein anderes Objekt weitergeben, wenn die Konstruktion passiert, wird nicht passieren und schwer zu fangen sein. – legends2k

+0

Also kann ich daraus schließen, dass ich, unabhängig vom Typ des Konstruktors (sei es Standard, Kopie, etc.), nichts anderes machen sollte als die Initialisierung der Mitglieder? – legends2k

+0

@ Legends2k: Ja. Der Standard erlaubt das Aufrufen von Kopierkonstruktoren bei der Rückgabe von Funktionen, was bedeutet, dass Ihr Code nicht versuchen sollte, sich auf Seiteneffekte in Kopierkonstruktoren zu verlassen. – UncleBens