Frage

Bitte beachten Sie die folgende Code,

struct foo
{
    foo()
    {
        std::cout << "Constructing!" << std::endl;
    }

    foo(const foo& f)
    {
        std::cout << "Copy constructing!" << std::endl;
    }

    ~foo()
    {
        std::cout << "Destructing.." << std::endl;
    }
};

foo get()
{
    foo f;
    return f;
}

int main()
{
    const foo& f = get();
    std::cout << "before return" << std::endl;
    return 0;
}

Ausgabe auf MSVC

Constructing!
Copy constructing!
Destructing..
before return
Destructing..

Ausgabe von GCC

Constructing!
before return
Destructing..

Das Ergebnis, das auf MSVC kommt sieht falsch.

Fragen

  1. AFAIK, produziert GCC das richtige Ergebnis hier. Warum MSVC wird unterschiedliche Ergebnisse geben und warum ist es Kopie Bau zu tun?
  2. const foo& f = get() und const foo f = get() erzeugt gleiche Leistung wegen Rückgabewert Optimierung. In diesem Fall, die Art und Weise des Schreibens soll bevorzugt werden?

Alle Gedanken ..

War es hilfreich?

Lösung

Ihr MSVC Build hat keine Optimierungen auf. Schalten Sie sie auf, werden Sie gleich Ausgang für beide erhalten.

GCC wird nur durchgeführt wird, standardmäßig RVO auf zeitlich begrenzt. Es ist im Grunde tun:

const foo& f = foo();

MSVC nicht. Es macht die foo in der Funktion, sie nach außen Kopieren der Funktion (ergo die Kopie-Konstruktoraufruf), die innere foo zerstörenden, dann bindet die Referenz.

Die beiden Ausgänge sind korrekt. RVO ist ein Fall, in dem der Standard explizit das beobachtbare Verhalten des Programms zu ändern.

Andere Tipps

Sie sehen die Rückgabewert Optimierung , die von einer Art ist kopieren elision . Beide Programme sind richtig; Der Compiler ist speziell die Möglichkeit der Beseitigung eines temporären gegeben, die nur dazu dient, Daten von einem dauerhaften Objekt zum anderen zu bewegen.

Die get () Funktion wird Bau der lokalen (Print Konstruieren!) Und Zurückgeben eines Foo Objekt nach Wert. Die Foo-Objekt zurückgegeben wird, muss erstellt werden und wird so über Kopie Bau getan (Drucken Kopieren Konstruktion!). Beachten Sie, dass dies der Objektwert des const Foo & f in Haupt zugeordnet ist.

Bevor die Zuordnung erfolgt jedoch die Funktion von get zurückgeben müssen () und lokale Variablen (das heißt foo f; in get ()) müssen vernichtet werden. (Drucken 1. Destructing ..) Von dort das Programm beendet wird (das heißt kehrt von Haupt-) dann das Objekt von get () zurückgegeben und zugewiesen „f“ zerstört wird. (Druck 2. Destructing ...)

Der Grund, um eine andere Ausgabe für die beiden Compiler sind zu sehen ist, dass GCC den Rückgabewert für get optimiert () und ist einfach const foo &f = get() zu const foo &f = foo ersetzt wird;

1) Dies geschieht, weil die verschiedenen Optimierungsstrategie. Weil Sie nicht Betreibers =, MSVC kann restrukturieren Code zu so etwas wie const Foo & f (get ()) daher Kopie onstructor ausgeführt wird. 2) Abhängig von, was Sie wollen acheive:

const foo& f = get();
f = get(); // Incorrect, const references cannot be reassigned.
const foo g = get();
g = get(); // Correct.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top