const Verweis auf temporäre und kopieren - C ++

8

Bitte beachten Sie den folgenden Code,

%Vor%

Ausgabe auf MSVC

%Vor%

Ausgabe von GCC

%Vor%

Das Ergebnis, das auf MSVC kommt, sieht falsch aus.

Fragen

  1. AFAIK, GCC liefert hier das korrekte Ergebnis. Warum gibt MSVC andere Ergebnisse und warum es Kopierkonstruktionen macht?
  2. const foo& f = get() und const foo f = get() erzeugt dieselbe Ausgabe aufgrund der Rückgabewertoptimierung. Welche Schreibweise sollte in diesem Fall bevorzugt werden?

Irgendwelche Gedanken ..

    
Navaneeth K N 05.03.2010, 04:50
quelle

4 Antworten

11

Ihr MSVC Build hat keine Optimierungen auf. Schalten Sie sie ein, Sie erhalten identische Ausgabe für beide.

GCC führt standardmäßig nur RVO auf Ihrem temporären System aus. Es macht im Grunde:

%Vor%

MSVC ist nicht. Es macht das foo in der Funktion, kopiert es nach außen in die Funktion (also den Aufruf von copy-constructor), zerstört das innere foo und bindet dann den Verweis.

Beide Ausgänge sind korrekt. RVO ist ein Fall, in dem der Standard explizit das beobachtbare Verhalten des Programms ändert.

    
GManNickG 05.03.2010, 05:01
quelle
1

Sie sehen die Rückgabewertoptimierung , die eine Art von Kopie Elision . Beide Programme sind korrekt; Der Compiler hat speziell die Möglichkeit, ein temporäres Objekt zu entfernen, das nur dazu dient, Daten von einem permanenten Objekt in ein anderes zu verschieben.

    
Potatoswatter 05.03.2010 05:07
quelle
1

Die Funktion get () konstruiert das lokale Konstrukt (print Constructing!) und gibt ein Foo-Objekt als Wert zurück. Das Foo-Objekt, das zurückgegeben wird, muss erstellt werden, und zwar über die Kopierkonstruktion (Print Copy constructing!). Beachten Sie, dass dies der Objektwert ist, der dem const foo & amp; f in main.

Bevor diese Zuweisung jedoch stattfindet, muss die Funktion von get () zurückkehren und lokale Variablen (d. h. foo f; in get ()) müssen zerstört werden. (print 1st Destructing ..) Von dort wird das Programm beendet (d. h. kehrt von main zurück), dann wird das von get () zurückgegebene und an "f" zugewiesene Objekt zerstört. (Drucken 2. Zerstören ...)

Der Grund, warum Sie für die beiden Compiler unterschiedliche Ausgaben sehen, ist, dass GCC den Rückgabewert für get () optimiert und einfach const foo &f = get() zu const foo &f = foo ;

ersetzt     
RC. 05.03.2010 05:15
quelle
-2

1) Dies geschieht aufgrund der unterschiedlichen Optimierungsstrategie. Weil Sie keinen Operator = haben, kann MSVC Code in etwas wie const foo & amp; f (get ()) führt daher den Kopieranzeiger aus. 2) Hängt davon ab, was Sie erreichen möchten:

%Vor%     
Sad Developer 05.03.2010 04:58
quelle