Parameter als Referenz übergeben unnötig?
-
Wie ist das eigentlich: Wenn ich einen Parameter als konstante Referenz kennzeichne, z.B.:
Bruch operator * (const Bruch&)möchte ich doch damit vermeiden, dass eine überflüssige Kopie erstellt wird. Ist das aber wirklich notwendig, oder nimmt der Compiler solche Optimierungen selber vor?
-
Dicker schrieb:
Wenn ich einen Parameter als konstante Referenz kennzeichne
Es gibt keine konstanten Referenzen, nenne sich bitte const-reference.
Dicker schrieb:
Bruch operator * (const Bruch&)möchte ich doch damit vermeiden, dass eine überflüssige Kopie erstellt wird.
Richtig.
Dicker schrieb:
Ist das aber wirklich notwendig, oder nimmt der Compiler solche Optimierungen selber vor?
Wenn er das machte, dann würde ja ein Sprachfeature ausraddiert werden, da by-value dann nicht mehr möglich wäre.
-
Klar soll der Compiler nicht einfach alle Parameter als const-reference behandeln. Aber kann der Compiler nicht erkennen, wann eine Übergabe per value keinen Sinn macht? Wenn z.B. nur lesend auf den Parameter zugegriffen würde. Ich stehe da gerade etwas auf dem Schlauch...
-
Und woher soll der Compiler wissen, dass auf den Parameter nur lesend zugegriffen wird? In der Regel sieht er den Quellcode der Zielfunktion nicht, sondern nur deren Signatur und muss dann Code bauen, um so eine Funktion aufzurufen. Und als die Funktion selber übersetzt wurde, musste Code erstellt werden, der annimmt dass die Funktion eben auch passend zu dieser Signatur aufgerufen wird, denn wie sollte man sie sonst aufrufen können?
P.S.: Außerdem hat Übergabe per value durchaus einige Vorteile.
-
Einleuchtend mit der getrennten Kompilierung. Aber könnte nicht der Linker den Zwischencode analysieren und dann entsprechend optimierten Code liefern?
Ich möchte einfach gerade nur herausfinden, wie wichtig es ist, den Code selber zu optimieren, und was der Compiler/Linker von sich aus schon optimiert. z.B. schlagen einige Leute vor, dass Bit-Schiebe-Operationen schneller seien als das multiplizieren mit einer 2er-Potenz. Oder das Benutzen von inline-Funktionen. Mir fehlt da der Durchblick...
-
[quote="Gugelmoser"]
Dicker schrieb:
Wenn ich einen Parameter als konstante Referenz kennzeichne
Es gibt keine konstanten Referenzen, nenne sich bitte const-reference.
Was ist denn das fuer ein Schwachsinn?
-
Dicker schrieb:
Einleuchtend mit der getrennten Kompilierung. Aber könnte nicht der Linker den Zwischencode analysieren und dann entsprechend optimierten Code liefern?
Fakt bleibt aber, dass der Code einfach eine andere Bedeutung bekommt. Eine const& und eine Kopie sind eben nicht genau das Gleiche, auch wenn sie teilweise dem gleichen Zweck dienen können.
Faustregel:
<= 8 Byte -> Kopie
> 8 Byte / Unbekannt -> const&
Und in Kopierkonstruktoren brauchst du z.B. immer eine const&.Dicker schrieb:
z.B. schlagen einige Leute vor, dass Bit-Schiebe-Operationen schneller seien als das multiplizieren mit einer 2er-Potenz.
Da haben sie recht, aber das wird der Compiler wohl optimieren. Was halt daran liegt, dass beide Operationen auch wirklich äquivalent sind.
Dicker schrieb:
Oder das Benutzen von inline-Funktionen. Mir fehlt da der Durchblick...
Das benutzt man eigentlich nur noch, wenn man freie Funktionen im Header definiert, damit der Linker sich nicht beschwert. Es ist halt ein Tipp an den Compiler, aber nach meiner Erfahrung wird der meistens ignoriert.

Edit:
SonQuatsch schrieb:
Was ist denn das fuer ein Schwachsinn?
LOL, dann zeig uns doch mal eine konstante Referenz.

-
Dicker schrieb:
Einleuchtend mit der getrennten Kompilierung. Aber könnte nicht der Linker den Zwischencode analysieren und dann entsprechend optimierten Code liefern?
Ja, das gibt es neuerdings und du darfst durchaus davon ausgehen, dass solche Optimierungen dann auch möglich werden.
Ich möchte einfach gerade nur herausfinden, wie wichtig es ist, den Code selber zu optimieren,
Das wichtigste ist erst einmal, dass der Algorithmus stimmt. Und man sollte keine großen Dummheiten machen. Denn eine unnötige Kopie eines großen Objekts wegzuoptimieren, ist dann doch schon eine ziemlich große Aktion, da machst du es lieber gleich richtig. Zwischen Kopie und const-Referenz besteht dann nämlich doch ein großer Unterschied, das lässt sich nicht unbedingt äquivalent austauschen. Und man sollte sich mal die C++11-Mittel angucken, dem Compiler noch mehr entgegen zu kommen, um solche Kopien zu vermeiden.
Kleinere Optimierungen in einfachen Rechnungen werden hingegen in der Regel extrem gut optimiert:z.B. schlagen einige Leute vor, dass Bit-Schiebe-Operationen schneller seien als das multiplizieren mit einer 2er-Potenz.
Dies zum Beispiel galt vielleicht mal vor vielen Jahrzehnten.
Oder das Benutzen von inline-Funktionen.
Noch so ein Beispiel dafür: Inline ist praktisch nur noch wegen seines Einflusses auf die Bindung von Bedeutung. Wenn der Compiler (oder ein optimierender Linker) den Funktionscode vorliegen hat, wird er die Möglichkeit von Inlining prüfen, egal ob inline oder nicht. Wenn er die Funktion nicht vorliegen hat, dann ist es egal ob sie inline ist oder nicht, dann wird eben ein normaler Call gemacht.
Daraus kannst du aber immerhin mitnehmen, dass es eine gute Idee ist, wenn kleine Funktionen dem Compiler als Code vorliegt (wofür sie in der Regel auch inline sein muss, falls man sie in mehreren ÜË benutzt). Oder falls dies nicht möglich ist, dann sollte man zur Linkzeit optimieren.
-
Eigentlich ist doch jede Referenz konstant, oder?
-
Eisflamme schrieb:
Eigentlich ist doch jede Referenz konstant, oder?
Eben. Konstante Referenz ist daher eine Tautologie. Und zwar eine böse, denn der Sprecher meint in der Regel etwas anderes, was dann aber gar nicht rüber kommt.
-
cooky451 schrieb:
Da haben sie recht, aber das wird der Compiler wohl optimieren. Was halt daran liegt, dass beide Operationen auch wirklich äquivalent sind.
Wasn Schwachsinn. Soll Prozessoren geben, bei dem eine Multiplikation schneller ist.
-
Eisflamme schrieb:
Eigentlich ist doch jede Referenz konstant, oder?
Jain. Eine Referenz kann immer nur auf das Objekt zeigen, dem sie bei der Inititalisierung zugewiesen wurde, aber du kannst eine Referenz halt nicht const qualifizieren. http://ideone.com/z692u
-
Okay, aber da wir ja const als Schlüsselwort und konstant als Adjektiv voneinander entkoppelt haben, stimmt meine Aussage ja so wie ich es meine.

-
314159265358979 schrieb:
cooky451 schrieb:
Da haben sie recht, aber das wird der Compiler wohl optimieren. Was halt daran liegt, dass beide Operationen auch wirklich äquivalent sind.
Wasn Schwachsinn. Soll Prozessoren geben, bei dem eine Multiplikation schneller ist.
Quark, mal wieder, leider.
Optimieren heißt nicht, alle *2 pauschal durch <<1 zu ersetzen, sondern die schnellere Anweisung zu wählen.
Was ist mir dir heute eigentlich wieder los? Du bettelst geradezu darum, über das Wochenende (mal wieder) eine Pause verpasst zu bekommen.
-
Wenn man mal von bösen Hacks absieht, ja.
-
SeppJ schrieb:
Optimieren heißt nicht, alle *2 pauschal durch <<1 zu ersetzen, sondern die schnellere Anweisung zu wählen.
Was du nicht sagst.

Mir ging es auch eher um "Da haben sie recht" und "Was halt daran liegt, dass beide Operationen auch wirklich äquivalent sind.".SeppJ schrieb:
Was ist mir dir heute eigentlich wieder los? Du bettelst geradezu darum, über das Wochenende (mal wieder) eine Pause verpasst zu bekommen.
Ahja. Dann leg mal los, wenns dir so viel Spaß macht.
-
cooky451 schrieb:
Eisflamme schrieb:
Eigentlich ist doch jede Referenz konstant, oder?
Jain. Eine Referenz kann immer nur auf das Objekt zeigen, dem sie bei der Inititalisierung zugewiesen wurde, aber du kannst eine Referenz halt nicht const qualifizieren. http://ideone.com/z692u
in der form
T const &ist die lesart einfach verkehrt: referenz auf const T.
da aber eine referenz immer auf ein objekt zeigt und immer auf das gleiche, ist es nicht unsinnig, den begriff "konstante referenz" als abkürzung für referenz auf const zu verwenden, was ja auch "const-reference" macht. wenn man allerdings nicht weiß, dass esT & constnicht gibt, würde es tatsächlich verwirrung machen, von const-reference oder konstanter referenz zu sprechen. referenz auf const ist in diesem fall besser, ansonsten egal.
-
oops schrieb:
da aber eine referenz immer auf ein objekt zeigt und immer auf das gleiche, ist es nicht unsinnig, den begriff "konstante referenz" als abkürzung für referenz auf const zu verwenden, was ja auch "const-reference" macht.
Doch, "konstante Referenz" ist immer unsinnig.
"Const reference" hingegen ist völlig angebracht, sogar der C++-Standard verwendet diesen Begriff. Und er bedeutet auch nicht "konstante Referenz", das wäre nämlich "constant reference".
-
Nexus schrieb:
"Const reference" hingegen ist völlig angebracht, sogar der C++-Standard verwendet diesen Begriff. Und er bedeutet auch nicht "konstante Referenz", das wäre nämlich "constant reference".
"constant reference" kann man aber genauso mit konstantenreferenz übersetzen, was genau dasselbe bedeutet, wie "const-reference", nämlich eine referenz auf eine konstante.
ich stimme dir schon zu, dass "konstante referenz" nicht eindeutig ist, eine konstanten-referenz wäre der eindeutige begriff; aber weil eine referenz immer auf das gleiche objekt verweist (und für diese definition keine wortspiele braucht), ist es absolut legitim, zu sagen "konstante referenz", wenn damit eine konstantenreferenz gemeint ist, weil aus dem kontext eindeutig klar wird, was gemeint ist.
-
Schön, dass du mit "Konstantenreferenz" noch einen weiteren Begriff einführst, den erst recht niemand versteht :p
Wie gesagt, "const reference" ist der offizielle Ausdruck. Auf deutsch würde ich ihn mit "Const-Referenz" übersetzen. Er bezieht sich auf das Schlüsselwort
const, was im Deutschen ebenfallsconstist. Es gibt sogar die Typdefinitionconst_referencebei Containern, die normalerweiseconst T&entspricht. Genauso wie beiconst_iterator, das ist ja auch kein konstanter Iterator. Gleiches gilt fürconst_pointer. Wieso sollte es bei Referenzen plötzlich anders sein?"Konstante Referenz" ist gerade für Anfänger unnötig verwirrend, weil der wörtliche Begriff 1. unnötige Information enthält (Referenzen sind immer konstant), 2. wichtige Information weglässt (ist das referenzierte Objekt konstant?) und 3. den Eindruck macht, dass es auch nicht-konstante Referenzen gäbe, was einfach nur falsch ist.
Während es sogar kürzer ist, "const reference" oder "Const-Referenz" zu schreiben, entspricht es auch dem im C++-Standard verwendeten Begriff und ist eindeutig. Also einigen wir uns doch bitte darauf
