inline, __inline, __forceinline
Specifikátory inline a __inline dávají pokyn kompilátoru k vložení kopie těla funkce na každé místo, odkud je funkce volána.
inline function_declarator;
__inline function_declarator; // Microsoft Specific
__forceinline function_declarator; // Microsoft Specific
Poznámky
Vložení (též vložené rozšíření nebo vkládání) nastane pouze v případě, že se analýza nákladů a přínosů kompilátoru jeví jako zisková.Vložené rozšíření řeší nároky volání funkce případných nákladů obsáhlejšího kódu.
Klíčové slovo __forceinline přepíše analýzy nákladů a přínosů a místo toho spoléhá na posouzení programátorem.Při používání __forceinline je třeba postupovat opatrně.Nerozlišení __forceinline může vést k obsáhlejšímu kódu s pouze minimálním ziskem výkonu nebo dokonce v některých případech i ke ztrátě výkonu (například v důsledku zvýšeného stránkování obsáhlejšího spustitelného souboru).
Pomocí vložených funkcí lze program urychlit, protože odstraňují režii spojenou s voláním funkcí.Vložené rozšířené funkce jsou předmětem optimalizace kódu nedostupným pro běžné funkce.
Kompilátor zpracovává možnosti vloženého rozšíření a klíčová slova jako návrhy.Není zaručeno, zda budou funkce vloženy.Nelze provést vynucení vložení funkce pomocí kompilátoru ani při použití klíčového slova __forceinline.Kompilátor při kompilaci pomocí /clr nevloží funkci, pokud jsou u funkce použity atributy zabezpečení.
Klíčové slovo inline je k dispozici pouze v jazyce C++.Klíčová slova __inline a __forceinline jsou k dispozici v jazycích C a C++.Z důvodu kompatibility s předchozími verzemi je _inline synonymem pro __inline.
Klíčové slovo inline říká kompilátoru o upřednostnění vloženého rozšíření.Kompilátor může však vytvořit samostatnou instanci funkce (vytvoření instance) a může vytvořit standardní spojení volání namísto vložení kódu.Jsou dva případy, kdy tato situace může nastat:
Rekurzivní funkce.
Funkce, které jsou v jednotce překladu označovány prostřednictvím ukazatele jinde.
Tyto důvody mohou ovlivňovat vkládání tak, jako mohou ostatní ovlivňovat vlastní uvážení kompilátoru. Při vkládání funkce byste se neměli spoléhat na specifikátor inline.
Stejně jako u běžných funkcí, neexistuje pořadí vyhodnocování argumentů vložené funkce.Ve skutečnosti může být odlišné od pořadí, ve kterém jsou vyhodnoceny argumenty při předávání pomocí protokolu volání normální funkce.
Nastavení optimalizace kompilátoru /Ob pomůže určit, zda skutečně dochází k vložení rozšířené funkce.
/LTGC provádí vkládání napříč moduly bez ohledu na to, zda tak bylo požadováno ve zdrojovém kódu.
Příklad 1
// inline_keyword1.cpp
// compile with: /c
inline int max( int a , int b ) {
if( a > b )
return a;
return b;
}
Členské funkce třídy mohou být deklarovány jako vložené pomocí klíčového slova inline nebo umístěním definice funkce v rámci definice třídy.
Příklad 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;
};
Specifické pro Microsoft
Klíčové slovo __inline odpovídá klíčovému slovu inline.
Dokonce i s pomocí příkazu __forceinline nemůže kompilátor provést vložení kódu za všech okolností.Kompilátor nemůže provést vložení funkce, pokud:
Funkce nebo její volající je zkompilován pomocí příkazu /Ob0 (výchozí možnost ladicích sestavení).
Funkce a volající používají různé druhy zpracování výjimek (zpracování výjimek jazyka C++ ve funkci, strukturované zpracování výjimek u volajícího).
Funkce má proměnný seznam argumentů.
Funkce používá vložené sestavení, dokud není zkompilována pomocí /Og, /Ox, /O1 nebo /O2.
Funkce je rekurzivní a není doplněna direktivou #pragma inline_recursion(on).Pomocí direktivy pragma jsou rekurzivní funkce vloženy do výchozí hloubky 16 volání.Chcete-li snížit hloubku vkládání, použijte direktivu pragma inline_depth.
Funkce je virtuální a je volána virtuálně.Přímá volání virtuálních funkcí mohou být vložena.
Program přebere adresu funkce a volání se provádí prostřednictvím ukazatele na funkci.Přímá volání funkcí, jejichž adresa byla odebrána mohou být vložena.
Funkce je také označena modifikátorem naked__declspec.
Pokud nemůže kompilátor provést vložení deklarované funkce pomocí příkazu __forceinline, pak vygeneruje upozornění úrovně 1.
Rekurzivní funkce mohou být nahrazeny vložením do hloubky určeného direktivou pragma inline_depth až do výše 16 volání.Následně jsou hluboké rekurzivní funkce považovány za volání instance funkce. Hloubka, do které jsou pomocí heuristiky vložení rekurzivní funkce prozkoumány nesmí překročit 16.Direktiva pragma Inline_recursion určuje vložení rozšíření aktuálně rozšiřované funkce.Více informací o nastavení kompilátoru (/Ob) naleznete v Vložení rozšířené funkce.
Specificka produktu Microsoft END
Další informace o použití specifikátoru inline, viz: