Heim >Backend-Entwicklung >C++ >Inline-Funktionen in C und C++
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 inline wurde, wurde der Code an jedem Punkt, an dem sie aufgerufen wurde, erweitert, anstatt den normalen Funktionsaufrufmechanismus wie folgt auszuführen:
Bei sehr kleinen 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 folgende 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 die Leistung des Programms 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 gegebenen Optionen ab.
Wenn der Compiler eine Funktion entweder nicht einbinden kann oder sich dafür entscheidet, nicht Sie zu warnen, dass er dies nicht getan hat (standardmäßig). Einige Compiler, z. B. gcc, verfügen über die Option -Winline, die Sie warnt und den Grund angibt, warum eine Funktion nicht eingebunden wurde.
Die Angabe von „inline“ ähnelt der Angabe von „register“ in älterem Code – es handelt sich bei beiden nur um 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 das Inlining ist, muss sie im Allgemeinen wie folgt sein:
Im Zweifelsfall profilieren Sie Ihren Code. Die Verwendung von Inline ist kein ein magisches „Mach mich schneller“-Schlüsselwort. Darüber hinaus kann eine übermäßige Verwendung von Inline zu einer Code-Aufblähung führen, die die Leistung Ihres Programms zusätzlich schlechter insgesamt macht.
Weitere Informationen finden Sie unter Die Inline-Krankheit.
Zu den Funktionen, die oft gute Kandidaten für das Inlining sind, gehören:
Eine ideale Inline-Funktion beide 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:
In order for the compiler to be able to inline a function, it has to be able to “see” its definition (not just its declaration) in every .c or .cpp file it’s used in just like a macro. Hence, an inline function must be defined in a header file.
Normally, a function, like everything else, must have exactly one definition by adhering to the one definition rule (ODR). However, since the definition of an inline function is “seen” in multiple .c or .cpp files, the ODR is suspended for that function.
It is possible to have different definitions for inline functions having the same name, but this results in undefined behavior since the compiler has no way to check that every definition is the same.
To inline a function in C++, all you need do is prefix the function definition with inline — that’s it. The compiler and/or linker will automatically discard all but one definition from the final executable file for you.
However, to inline a function in C, you additionally must explicitly tell the compiler into what .o file to put the one definition in the event the compiler is either unable or unwilling to inline a function via extern inline.
For example, in exactly one .c file, you would declare a function like:
// util.c extern inline int max_int( int, int );
That tells the compiler to “put the one definition for max_int() into util.o.”
Alternatively in C, you can instead declare an inline function static also:
static inline int max_int( int a, int b ) { return a > b ? a : b; }
If you do this, then:
Inline functions, if used judiciously, can yield performance gains. Generally, only very small functions are good candidates for inlining.
Starting in C++11, inline functions can alternatively be declared constexpr, but that’s a story for another time.
Das obige ist der detaillierte Inhalt vonInline-Funktionen in C und C++. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!