Frage

Wenn ich eine Funktion, die ein Objekt zurückgibt, aber das Rückgabewert wird nie vom Anrufer verwendet, wird der Compiler die Kopie optimiert weg? (Möglicherweise ein immer / manchmal / nie beantworten.)

Grund Beispiel:

ReturnValue MyClass::FunctionThatAltersMembersAndNeverFails()
{
    //Do stuff to members of MyClass that never fails
    return successfulResultObject;
}

void MyClass::DoWork()
{
    // Do some stuff
    FunctionThatAltersMembersAndNeverFails();
    // Do more stuff
}

In diesem Fall wird das ReturnValue Objekt überhaupt kopiert werden? Ist es auch gebaut werden? (Ich weiß, es hängt wahrscheinlich von dem Compiler, aber lassen Sie sich diese Diskussion einengen zu den beliebten modernen.)

EDIT: Lassen Sie uns diese ein wenig vereinfachen, da kein Konsens im allgemeinen Fall zu sein scheint. Was passiert, wenn ReturnValue ist ein int, und wir kehren 0 statt successfulResultObject?

War es hilfreich?

Lösung

Wenn die Return Klasse einen nicht-trivialen Copykonstruktor hat, muss der Compiler den Aufruf des Kopierkonstruktors beseitigen -. Es von der Sprache vorgeschrieben ist, dass es aufgerufen wird,

Wenn der Copykonstruktor inline ist, kann der Compiler in der Lage sein, den Anruf Inline, was wiederum könnte eine Beseitigung des viel seines Codes verursachen (auch abhängig davon, ob FunctionThatAltersMembersAndNeverFails ist inline).

Andere Tipps

Sie höchstwahrscheinlich, wenn die Optimierungsstufe bewirkt, dass sie den Code inline. Wenn nicht, würden sie verschiedene Übersetzungen des gleichen Codes zu erzeugen, haben zwei, um es, funktioniert die eine Menge von Rand Fall Probleme auftun könnte.

Die Linker Pflege dieser Art der Sache nehmen, auch wenn mit dem ursprünglichen Anrufer und sind in verschiedenen Übersetzungseinheiten genannt.

Wenn Sie einen guten Grund haben, besorgt über die CPU-Last zu einem Methodenaufruf gewidmet zu sein (vorzeitige Optimierung ist die Wurzel aller Übel,) Sie könnten die viele inlining Möglichkeiten, die Sie prüfen, einschließlich (Keuchen!) Ein Makro .

Wollen Sie wirklich auf dieser Ebene optimieren müssen?

Wenn Rückgabewert ist ein int und Sie kehren 0 (wie in der editierten Frage), dann ist dieses können weg optimiert erhalten.

Sie haben an der zugrunde liegenden Baugruppe zu suchen. Wenn die Funktion dann nicht inlined ist, wird die zugrunde liegende Montage eine mov eax ausführen, 0 (oder xor eax, eax) setzen EAX auf 0 (die in der Regel für Integer-Rückgabewerte verwendet wird) Ist die Funktion inlined, wird dies sicherlich erhalten wegoptimiert.

Aber das senario ist nicht allzu sinnvoll, wenn Sie sich Sorgen machen, was passiert, wenn Sie Objekte zurückgeben größer als 32-Bit. Sie müssen auf die Antworten auf die Frage unedit verweisen, die ein ziemlich gutes Bild malen: Wenn alles inlined wird dann das meiste davon wird optimiert werden. Wenn es nicht inlined ist, dann müssen die Funktionen auch aufgerufen werden, wenn sie nicht wirklich etwas tun, und das schließt den Konstruktor eines Objekts (da der Compiler nicht weiß, ob der Konstruktor globale Variablen geändert oder haben etwas anderes komisch) .

Ich bezweifle die meisten Compiler tun könnte, dass, wenn sie in verschiedenen Zusammen Objekte (zB. Unterschiedliche Dateien). Vielleicht, wenn sie in der gleichen Datei beide sind, sie können.

Es ist eine ziemlich gute Chance, dass ein Guckloch-Optimierer diese fangen. Viele (die meisten?) Compiler implementieren ein, so ist die Antwort wahrscheinlich „ja“.

Wie andere haben Notizen dies ist keine triviale Frage auf der AST Umschreiben Ebene.


Peephole Optimizern arbeiten auf einer Darstellung des Codes auf einem Niveau entspricht Assemblersprache (aber vor der Erzeugung des tatsächlichen Maschinencode). Es gibt eine Chance, die Last des Rückgabewertes in ein Register durch ein Überschreiben ohne Zwischenlese gefolgt zu bemerken, und nur die Last zu entfernen. Dies wird von Fall zu Fall entschieden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top