4 Stimmen

Warum ist es besser, func( const Class &value ) zu schreiben?

Warum sollte man die func( const Class &value ) und nicht nur func( Class value ) ? Sicherlich werden moderne Compiler mit jeder Syntax das effizienteste Ergebnis erzielen. Ist dies noch notwendig oder nur ein Überbleibsel aus den Tagen der nicht optimierenden Compiler?

  • Nur um hinzuzufügen, dass gcc für beide Syntaxen ähnliche Assembler-Code-Ausgaben erzeugt. Vielleicht tun andere Compiler nicht?

Offensichtlich ist dies nicht der Fall. Ich hatte vor langer Zeit aufgrund von Code den Eindruck, dass gcc dies tut, aber das Experimentieren beweist das Gegenteil. Der Dank geht an Michael Burr, dessen Antwort auf eine ähnliche Frage würde nominiert werden, wenn sie hier angegeben würde.

8 Stimmen

"Sicherlich werden moderne Compiler mit jeder Syntax das effizienteste Ergebnis erzielen." Computer tun nicht das, was man von ihnen will, sondern das, was man ihnen sagt!

3 Stimmen

"gcc wird für beide ähnliche Assemblercodes erzeugen" - können Sie diese Behauptung belegen? Wenn es wahr ist, hat der gcc einen Fehler.

2 Stimmen

Es ist möglich, dass gcc unter bestimmten Umständen ähnlichen Assembler-Code für beide erzeugt, vielleicht wenn ein int übergeben wird. Es sollte sicherlich nicht, wenn es eine nicht-triviale Kopie Konstruktor herum.

1voto

Amber Punkte 473552

Wenn Sie Ersteres verwenden und dann versuchen, die value aus Versehen, wird der Compiler eine Fehlermeldung ausgeben.

Wenn Sie Letzteres verwenden und dann versuchen, die value wird es nicht.

So ist es einfacher, Fehler zu erkennen.

1voto

dicroce Punkte 43066

Das erste Beispiel ist eine Referenzübergabe. Anstatt den Typ zu übergeben, übergibt C++ eine Referenz auf das Objekt (im Allgemeinen werden Referenzen mit Zeigern implementiert... Es handelt sich also wahrscheinlich um ein Objekt der Größe 4 Byte)... Im zweiten Beispiel wird das Objekt als Wert übergeben... wenn es sich um ein großes, komplexes Objekt handelt, dann ist es wahrscheinlich eine ziemlich schwergewichtige Operation, da es die Kopiekonstruktion einer neuen "Klasse" beinhaltet.

1voto

R Samuel Klatchko Punkte 72641

Der Grund, warum ein optimierender Compiler dies nicht für Sie erledigen kann, ist das Problem der separaten Kompilierung. Wenn der Compiler in C++ Code für einen Aufrufer erzeugt, hat er möglicherweise keinen Zugriff auf den Code der Funktion selbst. Die häufigste Aufrufkonvention, die ich kenne, sieht vor, dass der Aufrufer den Copy-Constructor aufruft, was bedeutet, dass es für die Kompilierung der Funktion selbst nicht möglich ist, den Copy-Constructor zu verhindern, wenn er nicht notwendig ist.

0 Stimmen

Tatsächlich führt gcc diese Optimierung durch, sogar mit -O0.

0 Stimmen

Hmm, ich habe es gerade getestet (mit gcc 4.2.1 unter Snow Leopard), indem ich ein printf() in den Kopierkonstruktor einer Klasse einfügte und dann ein Objekt dieser Klasse an eine Funktion übergab. Natürlich wurde der Kopierkonstruktor aufgerufen. Ich bin mir sogar ziemlich sicher, dass der C++-Standard verlangt, dass der Kopierkonstruktor in diesem Szenario aufgerufen wird - den Aufruf zu optimieren, wäre ein Compilerfehler.

0 Stimmen

@casualcoder - könnten Sie den Code posten, bei dem GCC Ihrer Meinung nach diese Optimierung durchführt? Tut er das auch, wenn der Aufrufer und der Aufgerufene nicht in der gleichen Quelldatei sind?

0voto

iain Punkte 10659

Die einzige Gelegenheit, einen Parameter als Wert zu übergeben, ist, wenn Sie den Parameter ohnehin kopieren wollen.

std::string toUpper( const std::string &value ) {
    std::string retVal(value);
    transform(retVal.begin(), retVal.end(), charToUpper());
    return retVal;
}

Oder

std::string toUpper( std::string value ) {
    transform(value.begin(), value.end(), charToUpper());
    return value;
}

In diesem Fall ist das zweite Beispiel genauso schnell wie das erste, wenn der Wertparameter ein normales Objekt ist, aber schneller, wenn der Wertparameter ein R-Wert ist.

Obwohl die meisten Compiler diese Optimierung bereits durchführen, erwarte ich nicht, dass ich mich bis C++0X auf diese Funktion verlassen werde, zumal ich davon ausgehe, dass sie die meisten Programmierer verwirren könnte, die sie wahrscheinlich wieder ändern würden.

Siehe Sie wollen Geschwindigkeit? Pass by Value. für eine bessere Erklärung, als ich sie geben könnte.

0 Stimmen

Sollte sein return value; in der zweiten Funktion.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X