C hat das Inline-Schlüsselwort hinzugefügt, das einer Funktionsdefinition vorangestellt werden kann, wie zum Beispiel:
inline int max_int( int a, int b ) { return a > b ? a : b; }
um dem Compiler einen „Hinweis“ zu geben, dass das Programm insgesamt von der Leistung profitieren könnte, wenn die Funktion inlined ist.
Bei einer Funktion, die inlined wurde, wurde der Code an jedem Punkt, an dem sie aufgerufen wurde, erweitert, anstatt den normalen Funktionsaufrufmechanismus wie folgt auszuführen:
Für sehr kleine Funktionen kann Inlining zu einer Leistungssteigerung führen. Aber wie bei fast allem anderen gibt es auch hier Kompromisse.
Das Inline-Schlüsselwort wurde auf C99 zurückportiert, jedoch mit etwas anderen Anforderungen – mehr später.
Inline-Funktionen sind wie funktionsähnliche Makros (und sollen viele ihrer Anwendungen ersetzen). Im Allgemeinen ist dies eine gute Sache, denn Inline-Funktionen sind Funktionen und verfügen über eine vollständige Funktionssemantik und nicht nur über eine bloße Textersetzung durch den Präprozessor, der weder C noch C versteht.
Ein naiv äquivalentes Makro zur Funktion max_int():
#define MAX_INT(A,B) A > B ? A : B /* bad implementation */
hat die folgenden Probleme:
Zusätzlich ein Makro:
Inline-Funktionen weisen keines dieser Probleme auf, können jedoch den gleichen Leistungsvorteil erzielen. Verwenden Sie daher Inline-Funktionen anstelle von funktionsähnlichen Makros.
Wie bereits erwähnt, ist die Angabe von „inline“ nur ein „Hinweis“ für den Compiler, dass das Programm insgesamt von der Inline-Funktion profitieren könnte. Dem Compiler steht es frei, den Hinweis zu ignorieren.
Warum? Denn es gibt Fälle, in denen es entweder keine gute Idee oder unmöglich ist. Eine Funktion ist entweder nicht inline oder normalerweise nicht inline, wenn eine der folgenden Bedingungen zutrifft:
Es kann andere Gründe geben. Es hängt alles stark von der Funktion, ihren Argumenten, dem Compiler und den ihr zugewiesenen Optionen ab.
Wenn der Compiler eine Funktion nicht inline einbinden kann oder möchte, wird er Sie nicht warnen, dass er dies nicht getan hat (standardmäßig). Einige Compiler, z. B. gcc, verfügen über eine -Winline-Option, die Sie warnt und Ihnen den Grund angibt, warum eine Funktion nicht eingebunden wurde.
Die Angabe von „inline“ ähnelt der Angabe von „register“ in älterem Code – beides sind nur Hinweise.
Bei den meisten Funktionen liegt der Großteil der Kosten für die Ausführung der Funktion im Funktionskörper und nicht im Funktionsaufrufmechanismus. Damit eine Funktion ein guter Kandidat für Inlining ist, muss sie im Allgemeinen wie folgt lauten:
Im Zweifelsfall profilieren Sie Ihren Code. Die Verwendung von Inline ist kein ein magisches „Mach mich schneller“-Schlüsselwort. Darüber hinaus kann die übermäßige Verwendung von Inline zu einer Code-Aufblähung führen, die die Leistung Ihres Programms insgesamt schlechter macht.
Weitere Informationen finden Sie unter Die Inline-Krankheit.
Zu den Funktionen, die häufig gute Kandidaten für das Inlining sind, gehören:
Eine ideale Inline-Funktion sowohl erhöht die Leistung und verringert die Codegröße.
Eine Einschränkung für jede Inline-Funktion besteht jedoch darin, dass bei einer Änderung ihrer Definition der gesamte Code, der sie verwendet, neu kompiliert werden muss.
Wenn eine Inline-Funktion tatsächlich vom Compiler eingebunden wird, kann der Compiler zusätzlich zum Weglassen des Codes für den normalen Funktionsaufrufmechanismus möglicherweise auch Folgendes tun:
Damit der Compiler eine Funktion einbinden kann, muss er ihre Definition (nicht nur ihre Deklaration) in jeder .c- oder .cpp-Datei, in der sie verwendet wird, „sehen“ können genau wie ein Makro. Daher muss eine Inline-Funktion in einer Header-Datei definiert sein.
Normalerweise muss eine Funktion, wie alles andere auch,genau eine Definition haben, indem die One Definition Rule (ODR) eingehalten wird. Da die Definition einer Inline-Funktion jedoch in mehreren .c- oder .cpp-Dateien „gesehen“ wird, wird der ODR für diese Funktion ausgesetzt.
Es ist möglich, unterschiedliche Definitionen für Inline-Funktionen mit demselben Namen zu haben, aber dies führt zu undefiniertem Verhalten, da der Compiler keine Möglichkeit hat, zu überprüfen, ob alle Definitionen gleich sind.Um eine Funktion in C zu integrieren, müssen Sie der Funktionsdefinition lediglich „inline“ voranstellen – fertig. Der Compiler und/oder Linker verwirft für Sie automatisch alle Definitionen bis auf eine aus der endgültigen ausführbaren Datei.
Um jedoch eine Funktion in C zu integrieren, müssen Sie dem Compiler zusätzlich
explizit mitteilen, in welche .o-Datei die eine Definition eingefügt werden soll, falls der Compiler entweder nicht in der Lage oder nicht bereit ist, eine Funktion über zu integrieren extern inline.
Zum Beispiel würden Sie ingenau einer .c-Datei eine Funktion deklarieren wie:
// util.c extern inline int max_int( int, int );Das weist den Compiler an, „die eine Definition für max_int() in util.o einzufügen.“
Alternativ können Sie in C auch eine statische Inline-Funktion deklarieren:
// util.c extern inline int max_int( int, int );Wenn Sie dies tun, dann:
sehr kleine Funktionen gute Kandidaten für Inlining.
Ab C 11 können Inline-Funktionen alternativ als constexpr deklariert werden, aber das ist eine Geschichte für ein anderes Mal.Referenzen
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3