inline, __inline, __forceinline
Die Spezifizierer inline und __inline weisen den Compiler an, eine Kopie des Funktionstexts an jeder Stelle einzufügen, an der die Funktion aufgerufen wird.
inline function_declarator;
__inline function_declarator; // Microsoft Specific
__forceinline function_declarator; // Microsoft Specific
Hinweise
Die Einfügung (bezeichnet als Inlineerweiterung oder Inlinekonstrukt) wird nur ausgeführt, wenn die Kosten-Nutzen-Analyse des Compilers dies als sinnvoll bewertet. Eine Inlineerweiterung verringert den Funktionsaufruf-Mehraufwand, möglicherweise auf Kosten der größeren Codegröße.
Das __forceinline-Schlüsselwort überschreibt die Kosten-Nutzen-Analyse und basiert stattdessen auf dem Urteil des Programmierers. Sie sollten __forceinline mit Vorsicht verwenden. Die wahllose Verwendung von __forceinline kann zu längerem Code mit nur marginalen Leistungssteigerungen oder in einigen Fällen sogar mit Leistungsverlusten führen (beispielsweise aufgrund des erweiterten Pagings einer größeren ausführbaren Datei).
Die Verwendung von Inlinefunktionen kann das Programm schneller machen, da so der Mehraufwand vermieden wird, der Funktionsaufrufen zugeordnet ist. Inline erweiterte Funktionen unterliegen Codeoptimierungen, die für normale Funktionen nicht verfügbar sind.
Der Compiler behandelt die Inlineerweiterungsoptionen und -Schlüsselwörter als Vorschläge. Es gibt keine Garantie, dass Funktionen inline gestellt werden. Sie können den Compiler nicht zwingen, eine bestimmte Funktion inline zu setzen, auch nicht mit dem __forceinline-Schlüsselwort. Beim Kompilieren mit /clr setzt der Compiler eine Funktion nicht inline, wenn auf die Funktion Sicherheitsattribute angewendet werden.
Das inline-Schlüsselwort ist nur in C++ verfügbar. Die Schlüsselwörter __inline und __forceinline sind sowohl in C als auch in C++ verfügbar. Aus Gründen der Kompatibilität mit früheren Versionen ist _inline ein Synonym für __inline.
Das Schlüsselwort inline teilt dem Compiler mit, dass eine Inlineerweiterung bevorzugt wird. Jedoch kann der Compiler eine separate Instanz der Funktion erstellen (instanziieren) und Standardaufrufbindungen erstellen, anstatt den Code inline einzufügen. Zwei Fälle, in denen dies auftreten kann, sind:
Rekursive Funktionen.
Funktionen, auf die durch einen Zeiger an anderer Stelle in der Übersetzungseinheit verwiesen wird.
Diese Gründe beeinträchtigen möglicherweise Inlinekonstrukte, wie ggf. auch andere, je nach Compilereinstellung. Sie sollten nicht vom inline-Spezifizierer abhängen, um eine Funktion inline zu setzen.
Wie bei normalen Funktionen so ist auch bei den Argumenten einer Inlinefunktion die Reihenfolge der Auswertung nicht festgelegt. Tatsächlich kann sie sich von der Reihenfolge unterscheiden, in der die Argumente ausgewertet werden, wenn sie mithilfe des normalen Funktionsaufrufprotokolls übergeben werden.
Mit der /Ob-Compileroptimierungsoption kann bestimmt werden, ob die Inlinefunktionserweiterung tatsächlich stattfindet.
/LTCG führt modulübergreifende Inlinekonstrukte aus, unabhängig davon, ob dies im Quellcode angefordert wurde.
Beispiel 1
// inline_keyword1.cpp
// compile with: /c
inline int max( int a , int b ) {
if( a > b )
return a;
return b;
}
Die Memberfunktionen einer Klasse können inline deklariert werden, entweder indem das inline-Schlüsselwort verwendet oder die Funktionsdefinition innerhalb der Klassendefinition platziert wird.
Beispiel 2
// inline_keyword2.cpp
// compile with: /EHsc /c
#include <iostream>
using namespace std;
class MyClass {
public:
void print() { cout << i << ' '; } // Implicitly inline
private:
int i;
};
Microsoft-spezifisch
Das __inline-Schlüsselwort ist äquivalent zu inline.
Auch mit __forceinline kann der Compiler Code nicht in allen Fällen inline setzen. Der Compiler kann keine Funktion inline setzen, wenn Folgendes der Fall ist:
Die Funktion oder ihr Aufrufer werden mit /Ob0 kompiliert (die Standardoption für Debugbuilds).
Die Funktion und der Aufrufer verwenden unterschiedliche Typen der Ausnahmebehandlung (C++-Ausnahmebehandlung zum einen, strukturierte Ausnahmebehandlung zum anderen).
Die Funktion weist eine variable Argumentliste auf.
Die Funktion verwendet eine Inlineassembly, es sei denn, sie wird mit /Og, /Ox, /O1, oder /O2 kompiliert.
Die Funktion ist rekursiv und geht nicht mit #pragma inline_recursion(on) einher. Mit dem Pragma werden rekursive Funktionen mit einer Standardtiefe von 16 Aufrufen inline gesetzt. Um die Tiefe bei Inlinekonstrukten zu reduzieren, verwenden Sie das inline_depth-Pragma.
Die Funktion ist virtuell und wird virtuell aufgerufen. Direkte Aufrufe virtueller Funktionen können inline gesetzt werden.
Das Programm akzeptiert die Adresse der Funktion, und der Aufruf erfolgt über den Zeiger auf die Funktion. Direkte Aufrufe von Funktionen, deren Adresse akzeptiert wurden, können inline gesetzt werden.
Die Funktion wird auch mit dem naked __declspec-Modifizierer gekennzeichnet.
Wenn der Compiler eine Funktion, die mit __forceinline deklariert ist, nicht inline stellen kann, wird eine Warnung der Stufe 1 ausgelöst.
Rekursive Funktionen können inline ersetzt werden, mit einer vom inline_depth-Pragma angegebenen Tiefe von bis zu maximal 16 Aufrufen. Nach dieser Tiefe werden rekursive Funktionsaufrufe als Aufrufe einer Instanz der Funktion behandelt. Die Tiefe, bis zu der rekursive Funktionen durch die Inlineheuristik geprüft werden, kann 16 nicht überschreiten. Das inline_recursion-Pragma steuert die Inlineerweiterung einer Funktion, die aktuell erweitert wird. Weitere Informationen erhalten Sie unter der (/Ob)-Compileroption Inlinefunktionserweiterung.
Ende Microsoft-spezifisch
Weitere Informationen zum Verwenden des inline-Bezeichners finden Sie unter: