const Referenz auf temporäre Kuriosität

7

Wir alle wissen, dass solche Dinge in C ++ gültig sind:

%Vor%

während:

%Vor%

ist nicht.

In eine aktuelle Frage , zu der das Gespräch geführt hat diese Regel. Das OP hatte einen Code veröffentlicht, der eindeutig an UB erinnert. Aber ich hätte erwartet, dass eine modifizierte Version funktioniert (Dies ist die modifizierte Version):

%Vor%

Dies druckt Müll auf einigen Maschinen, 10 auf anderen ... klingt wie UB für mich :-). Aber dann dachte ich, naja A ist im Grunde eine verherrlichte int alles was es tut, initialisiert man und liest es. Warum nicht einfach A an int aufrufen und sehen, was passiert:

%Vor%

Es druckt 10 jedes Mal. Es scheint zumindest zu sein, wie die const-Referenzregel für die int -Version gilt, aber nicht für die Klassenversion. Sind sie beide einfach UB wegen der Verwendung des Heaps? Habe ich nur Glück mit der int Version, weil die Kompilierung alle const s durchgesehen hat und einfach direkt 10 ausgedruckt hat? Welchen Aspekt der Regel vermisse ich?

    
Evan Teran 22.06.2010, 23:11
quelle

3 Antworten

15

Es zeigt einfach, dass das Analysieren des Sprachverhaltens, indem es es im Compiler versucht, normalerweise keine brauchbaren Ergebnisse liefert. Ihre beiden Beispiele sind aus dem gleichen Grund ungültig.

Die Lebensdauer des temporären Objekts wird nur erweitert, wenn Sie das temporäre Objekt als direkten Initialisierer für einen const-Verweis verwenden. Nur so wird eine "lebenslange" Verknüpfung zwischen dem Verweis und dem temporären Objekt hergestellt.

Wenn Sie versuchen, ein temporäres Argument als Konstruktor zu übergeben und einen const-Verweis innerhalb des Konstruktors anzuhängen, wird der oben erwähnte Link nicht hergestellt und die Lebensdauer des temporären Objekts wird nicht verlängert.

Gemäß dem C ++ Standard, wenn Sie dies tun

%Vor%

Die Lebensdauer des temporären Objekts wird nur bis zum Ende des Konstruktors verlängert. Sobald der Konstruktor fertig ist, stirbt das temporäre, was bedeutet, dass dies

%Vor%

ist ungültig.

Ihr Experiment mit int scheint einfach "zu funktionieren", rein zufällig.

    
AnT 22.06.2010, 23:23
quelle
3

Du hast gerade Glück gehabt. Ändere B :: b zu diesem:

%Vor%

gibt Zufallszahlen aus.

    
Pete Kirkham 22.06.2010 23:26
quelle
3
  

Es wird jedes Mal 10 Mal gedruckt.

Ändern Sie die Hauptfunktion etwas und es wird nicht mehr 10 gedruckt:

%Vor%
  

Wie wird diese Verbindung auf welcher Ebene hergestellt?

Siehe 12.2 [class.temporary] §4 und §5:

  

Temporäre Objekte werden als letzter Schritt bei der Auswertung des vollständigen Ausdrucks gelöscht, der (lexikalisch) den Punkt enthält, an dem sie erstellt wurden.

     

Es gibt zwei Kontexte, in denen Provisorien an einem anderen Punkt als dem Ende des Volltexts zerstört werden.   Der erste Kontext ist [...]

     

Der zweite Kontext ist, wenn eine Referenz an eine temporäre gebunden ist. Das Temporäre, an das die Referenz gebunden ist, oder das Temporäre, das das vollständige Objekt eines Unterobjekts ist, an das die Referenz gebunden ist, bleiben für die Lebensdauer der Referenz bestehen, außer: [...]

     

Eine temporäre Bindung an einen Referenzparameter in einem Funktionsaufruf bleibt bis zum Abschluss des vollständigen Ausdrucks bestehen, der den Aufruf enthält.

In diesem Fall wird das temporäre Objekt nach der Auswertung des vollständigen Ausdrucks new B(A(10)) zerstört.

    
fredoverflow 22.06.2010 23:27
quelle

Tags und Links