Wie geht Compiler mit r-values um
-
XSpille schrieb:
Also folgende Zeile kommt mir ziemlich dubios vor:
int&& x = 5 + 4;Du sagst ja selbst, landet 5+4 auf dem Stack (angenommen der Compiler optimiert die Addtion nicht weg, was er natürlich macht). Damit kann der Wert 9 auf dem Stack nach dem Semikolon zerstört werden. Somit hast du eine Dangling-Reference.
Das Verhalten ist vermutlich undefiniert.
Ich bin jetzt (noch) nicht der rvalue-Profi und lasse mich gerne eines besseren belehren.Ich habe zwar den Standard nicht gelesen, aber so etwas Einfaches wird wohl kaum undefiniertes Verhalten sein. Dann könnte man ja besser die Syntax verbieten.
//darf man ja auch: const int &x = 5 + 4;XSpille schrieb:
Ich stell mal eine andere Frage:
Machen rvalue-Referenzen bei einfachen Datentypen überhaupt Sinn?Nein
-
TyRoXx schrieb:
//darf man ja auch: const int &x = 5 + 4;Das ist wirklich standardkonformes C++? Ich hätte das intuitiv auch als undefiniert abgestempelt...
Man lernt nie aus

Aber wie kann das verwirklicht werden? Die 9 liegt doch irgendwo auf dem Stack, oder? Und man hat ja keinen Anhaltspunkt, wann sie zerstörrt werden darf.
Gruß,
XSpilleEDIT: Das kann doch eigentlich nur gehen, wenn das Ergebnis zur Kompilierzeit bekannt ist. Und somit optimiert der Compiler doch

-
XSpille schrieb:
Also folgende Zeile kommt mir ziemlich dubios vor:
int&& x = 5 + 4;Du sagst ja selbst, landet 5+4 auf dem Stack (angenommen der Compiler optimiert die Addtion nicht weg, was er natürlich macht). Damit kann der Wert 9 auf dem Stack nach dem Semikolon zerstört werden. Somit hast du eine Dangling-Reference.
Nö, die Lebenszeit des temporären Objekts verlängert sich auf die der Referenz.
Zumindest lese ich das aus 12.2p5 heraus.
Und wenn ich das richtig verstanden habe, ist der einzige Unterschied zwischen lvalue- und rvalue-Referenzen, das letztere (auch) an rvalues gebunden werden können.
Das heißt die obige Initialisierung bindet eine rvalue-Referenz an ein temporäres int-Objekt mit dem Wert 9. Die rvalue-Referenz selbst stellt aber ein lvalue dar (?), weshalb man eine lvalue-Referenz im return-Statement von foo daran binden kann. Beim Beenden der Funktion wird das temporäre Objekt zerstört, und dann haben wir eine dangling reference.
Korrigiert mich, wenn ich falsch liege. Irgendjemand sollte mal einen schönen FAQ-Artikel dazu schreiben.
edit:
Aber wie kann das verwirklicht werden? Die 9 liegt doch irgendwo auf dem Stack, oder? Und man hat ja keinen Anhaltspunkt, wann sie zerstörrt werden darf.
Die 9 ist IMHO erstmal gar kein Objekt, sondern einfach ein Wert (ein prvalue). Es wird extra für die Referenz ein temporäres Objekt angelegt.
-
DANKE TyRoXx, DANKE Bashar
Bashar schrieb:
Nö, die Lebenszeit des temporären Objekts verlängert sich auf die der Referenz.
Wußte ich auch noch nicht...
Macht Sinn...

-
Nur bei konstanten Referenzen wird die Lebenszeit verlängert: http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
-
Bashar schrieb:
Die rvalue-Referenz selbst stellt aber ein lvalue dar (?)
Die Referenz selbst nicht, ein Ausdruck, in dem sie erscheint, dagegen schon.
-
Oberon_0 schrieb:
Nur bei konstanten Referenzen wird die Lebenszeit verlängert: http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
Der Artikel ist schon ziemlich alt und berücksichtigt rvalue-Referenzen nicht.
-
Oberon_0 schrieb:
Nur bei konstanten Referenzen wird die Lebenszeit verlängert: http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
Das ist zu einer Zeit geschrieben worden, als rvalue-Referenzen lediglich als Entwurf existierten. Und C++03 sind Referenzen auf const nun mal die einzigen Weg (mit einer winzigen Ausnahme), die an temporäre Objekte binden können.
Jedenfalls verweist 12.2/5 nicht auf irgendeine bestimmte Art von Referenz. Wenn sie überhaupt an das Argument gebunden werden kann, dann verlängert sich die Lebenszeit des Objektes wie dort beschrieben.
-
Bin jezt etwas verwirrt, wenn man so etwas hat
const int& foo() { const int &x = 5 + 4; return x; } int main() { const int& a = foo(); return 0; }Dann ist doch das a eine dangling Reference oder?
Gruß

-
MatheStein schrieb:
Bin jezt etwas verwirrt, wenn man so etwas hat
int& foo() { const int &x = 5 + 4; return x; } int main() { int& a = foo(); return 0; }Dann ist doch das a eine dangling Reference oder?
Gruß

Wenn du aus dem int& ein const int& machst, ja.
-
Ups, habs schon verbesser ^^ Vielen Dank
