Next: Defaultargumente
Up: Funktionen und Operatoren
Previous: Weitere Operatoren
Folgende Operationen finden bei einem Funktionsaufruf und beim
Rückkehren aus einer Funktion statt:
- Sichern des lokalen Programmkontextes (z.B. Variablen,
die in CPU-Registern gehalten wurden, Rücksprungadresse)
auf den Stapel (Stack).
- Kopieren der Funktionsargumente (Pointer oder Klassen) aus dem lokalen
Kontext auf den Stapel (Stack), um Überschreiben aus der Funktion heraus
zu verhindern.
- Anspringen der Einsprungadresse der Funktion.
- Ausführen der Anweisungen in der Funktion. Berechnung des
Rückgabewertes.
- Ablegen/Kopieren des Rückgabewertes auf den Stapel.
- Rücksprung in das aufrufende Programm, Wiederherstellen des
lokalen Kontextes
Die Schritte 1, 5 und 6 stellen dabei Aufwand dar, der vermieden
werden kann, indem man den Funktionsaufruf umgeht. Für
kurze Funktionen, die in einem Programm sehr häufig aufgerufen
werden, können diese Schritte
einen signifikanten Anteil der Gesamtausführungszeit des Programms
darstellen. Diesen Zusatzaufwand umgeht man durch sogenanntes Inlining
der Funktion; gewissermassen wird dabei der Funktionstext an der
entsprechenden Stelle im ablaufenden Programm eingefügt.
In C hat man an dieser Stelle häufig Makros verwendet, die aber den
Nachteil unintuitiver Nebeneffekte haben.
#define SQR(a) ((a)*(a))
int b=2,c;
c = SQR(b++); // c = ((a++) * (a++));
// c is now 2*3 = 6, b is 4 after 2(!) increments
Der Schritt
2 bleibt in der Regel nötig, weil natürlich auch weiterhin keine
Variablen unkontrolliert verändert werden dürfen.
Wenn man in C++ im Header-file (siehe Abschnitt )
eine Funktion definiert und mit dem Schlüsselwort inline
kennzeichnet, so versucht der Compiler,
den Funktionsaufruf durch Inlining wegzuoptimieren.
inline int sqr(int a){ return a*a; }
int b=2, c;
c = sqr(b++); // b++ is evaluated once, hence c is now 4, b is 3
Da der Nachteil des Inlining vergrößerte Programme sind, sollte
man mit diesem Mittel sparsam umgehen. Lange Funktionen gehören in
Implementierungsdateien und nicht in die header-Dateien.
Klassen-Elementfunktionen, die im Klassenkörper definiert werden,
behandelt der Compiler automatisch als inline.
Zusammenfassung:
(i) inlining ist gut für kurze Funktionen, die effizient gemacht
werden müssen;
(ii) inline Funktionen müssen im header definiert werden;
(iii) Elementfunktionen, die im header definiert sind, sind per
default inline.
Next: Defaultargumente
Up: Funktionen und Operatoren
Previous: Weitere Operatoren
© R.Hilfer et al., ICA-1, Univ. Stuttgart
28.6.2002