logo

Inline funkce v C++

C++ poskytuje inline funkce pro snížení režie volání funkcí. Inline funkce je funkce, která se při volání rozbalí v řádku. Když je volána inline funkce, celý kód inline funkce je vložen nebo nahrazen v místě volání inline funkce. Tuto substituci provádí kompilátor C++ v době kompilace. Inline funkce může zvýšit účinnost, pokud je malá.

Syntax:



inline return-type function-name(parameters) { // function code }>
Inline funkce v c++

Pamatujte, že vkládání je pouze požadavek na kompilátor, nikoli příkaz. Kompilátor může ignorovat požadavek na vložení.

Kompilátor nemusí provádět vkládání za takových okolností, jako jsou:

  1. Pokud funkce obsahuje smyčku. ( na, chvíli a do-chvíli )
  2. Pokud funkce obsahuje statické proměnné.
  3. Pokud je funkce rekurzivní.
  4. Pokud je návratový typ funkce jiný než void a příkaz return v těle funkce neexistuje.
  5. Pokud funkce obsahuje příkaz switch nebo goto.

Proč se používají funkce Inline?

Když program provede instrukci volání funkce, CPU uloží paměťovou adresu instrukce následující po volání funkce, zkopíruje argumenty funkce do zásobníku a nakonec předá řízení zadané funkci. CPU pak provede kód funkce, uloží návratovou hodnotu funkce do předem definovaného paměťového místa/registru a vrátí řízení volající funkci. To se může stát režií, pokud je doba provedení funkce kratší než doba přepnutí z funkce volajícího na volanou funkci (volané).



U funkcí, které jsou velké a/nebo provádějí složité úkoly, je režie volání funkce obvykle nevýznamná ve srovnání s dobou, kterou funkce potřebuje ke spuštění. U malých, běžně používaných funkcí je však čas potřebný k provedení volání funkce často mnohem delší než čas potřebný ke skutečnému provedení kódu funkce. K této režii dochází u malých funkcí, protože doba provedení malé funkce je kratší než doba sepnutí.

Inline funkce Výhody:

  1. Režie volání funkce se nevyskytuje.
  2. Při volání funkce také šetří režii proměnných push/pop na zásobníku.
  3. Ušetří také režii zpětného volání z funkce.
  4. Když vložíte funkci, můžete povolit kompilátoru provádět kontextově specifickou optimalizaci těla funkce. Takové optimalizace nejsou možné pro normální volání funkcí. Další optimalizace lze získat zvážením toků volajícího kontextu a volaného kontextu.
  5. Inline funkce může být užitečná (pokud je malá) pro vestavěné systémy, protože inline může poskytnout méně kódu než funkce nazývaná preambule a návrat.

Inline funkce Nevýhody:

  1. Přidané proměnné z inline funkce spotřebovávají další registry. Po in-lining funkci, pokud se číslo proměnné, která bude používat registr, zvýší, pak mohou vytvářet režii na využití zdrojů proměnné registru. To znamená, že když je v místě volání funkce nahrazeno tělo funkce, vloží se také celkový počet proměnných používaných funkcí. Zvýší se tedy také počet registrů, které budou použity pro proměnné. Takže pokud se po funkci vkládání čísel proměnných drasticky zvýší, pak by to jistě způsobilo režii na využití registru.
  2. Pokud použijete příliš mnoho inline funkcí, bude velikost binárního spustitelného souboru velká kvůli duplikaci stejného kódu.
  3. Příliš mnoho inliningu může také snížit četnost zásahů do mezipaměti instrukcí, čímž se sníží rychlost načítání instrukcí z vyrovnávací paměti na rychlost primární paměti.
  4. Inline funkce může zvýšit režii kompilace, pokud někdo změní kód uvnitř inline funkce, pak musí být celé místo volání znovu zkompilováno, protože kompilátor by musel znovu nahradit veškerý kód, aby odrážel změny, jinak bude pokračovat se starým funkčnost.
  5. Inline funkce nemusí být užitečné pro mnoho vestavěných systémů. Protože ve vestavěných systémech je velikost kódu důležitější než rychlost.
  6. Vložené funkce mohou způsobit přerušování, protože vkládání může zvětšit velikost binárního spustitelného souboru. Narušení paměti způsobí snížení výkonu počítače. Následující program demonstruje použití funkce inline.

Příklad:

C++






#include> using> namespace> std;> inline> int> cube(>int> s) {>return> s * s * s; }> int> main()> {> >cout <<>'The cube of 3 is: '> << cube(3) <<>' '>;> >return> 0;> }>

>

>

Výstup

The cube of 3 is: 27>

Inline funkce a třídy

Je také možné definovat inline funkci uvnitř třídy. Ve skutečnosti jsou všechny funkce definované uvnitř třídy implicitně inline. I zde se tedy uplatňují všechna omezení inline funkcí. Pokud potřebujete explicitně deklarovat inline funkci ve třídě, pak stačí deklarovat funkci uvnitř třídy a definovat ji mimo třídu pomocí klíčového slova inline.

Syntax:

class S { public: inline int square(int s) // redundant use of inline { // this function is automatically inline // function body } };>

Výše uvedený styl je považován za špatný styl programování. Nejlepším programovacím stylem je jednoduše napsat prototyp funkce do třídy a zadat jej jako inline v definici funkce.

Například:

class S { public: int square(int s); // declare the function }; inline int S::square(int s) // use inline prefix { }>

Příklad:

C++




// C++ Program to demonstrate inline functions and classes> #include> using> namespace> std;> class> operation {> >int> a, b, add, sub, mul;> >float> div>;> public>:> >void> get();> >void> sum();> >void> difference();> >void> product();> >void> division();> };> inline> void> operation ::get()> {> >cout <<>'Enter first value:'>;> >cin>> a;> >cout <<>'Enter second value:'>;> >cin>> b;> }> inline> void> operation ::sum()> {> >add = a + b;> >cout <<>'Addition of two numbers: '> << a + b <<>' '>;> }> inline> void> operation ::difference()> {> >sub = a - b;> >cout <<>'Difference of two numbers: '> << a - b <<>' '>;> }> inline> void> operation ::product()> {> >mul = a * b;> >cout <<>'Product of two numbers: '> << a * b <<>' '>;> }> inline> void> operation ::division()> {> >div> = a / b;> >cout <<>'Division of two numbers: '> << a / b <<>' '>;> }> int> main()> {> >cout <<>'Program using inline function '>;> >operation s;> >s.get();> >s.sum();> >s.difference();> >s.product();> >s.division();> >return> 0;> }>

>

kde jsou nastavení prohlížeče
>

Výstup:

Enter first value: 45 Enter second value: 15 Addition of two numbers: 60 Difference of two numbers: 30 Product of two numbers: 675 Division of two numbers: 3>

Co je na makru špatného?

Čtenáři znalí jazyka C vědí, že jazyk C používá makro. Preprocesor nahrazuje všechna volání maker přímo v kódu makra. Místo makra se doporučuje vždy používat funkci inline. Podle Dr. Bjarne Stroustrupa není tvůrce maker C++ v C++ téměř nikdy nutný a jsou náchylná k chybám. S používáním maker v C++ jsou určité problémy. Makro nemá přístup k soukromým členům třídy. Makra vypadají jako volání funkcí, ale ve skutečnosti nejsou.

Příklad:

C++




// C++ Program to demonstrate working of macro> #include> using> namespace> std;> class> S {> >int> m;> public>:> >// error> #define MAC(S::m)> };>

>

>

Výstup:

Error: '::' may not appear in macro parameter list #define MAC(S::m)>

Kompilátor C++ kontroluje typy argumentů inline funkcí a potřebné převody se provádějí správně. Makro preprocesoru to neumí. Další věcí je, že makra jsou spravována preprocesorem a inline funkce jsou spravovány kompilátorem C++. Pamatujte: Je pravda, že všechny funkce definované uvnitř třídy jsou implicitně inline a kompilátor C++ bude provádět inline volání těchto funkcí, ale kompilátor C++ nemůže provádět inline, pokud je funkce virtuální. Důvod volání virtuální funkce se řeší za běhu namísto v době kompilace. Virtuální znamená čekání do běhu a inline znamená během kompilace, pokud kompilátor neví, která funkce bude volána, jak může provést inlining? Další věc, kterou je třeba si zapamatovat, je, že je užitečné vytvořit funkci inline, pouze pokud je čas strávený během volání funkce více ve srovnání s časem provedení těla funkce.

Příklad, kdy funkce inline nemá vůbec žádný účinek:

inline void show() { cout << 'value of S = ' << S << endl; }>

Spuštění výše uvedené funkce trvá poměrně dlouho. Obecně platí, že funkce, která provádí vstupně-výstupní (I/O) operaci, by neměla být definována jako inline, protože tráví značné množství času. Technicky vložení funkce show() má omezenou hodnotu, protože doba, kterou I/O příkaz zabere, daleko překračuje režii volání funkce. V závislosti na kompilátoru, který používáte, vám kompilátor může zobrazit varování, pokud funkce není rozbalena inline.

Programovací jazyky jako Java a C# nepodporují inline funkce. Ale v Javě může kompilátor provést inlining, když je volána malá finální metoda, protože konečné metody nelze přepsat podtřídami a volání konečné metody je vyřešeno v době kompilace.

V C# JIT kompilátor může také optimalizovat kód vložením volání malých funkcí (jako je nahrazení těla malé funkce, když je volána ve smyčce). Poslední věc, kterou je třeba mít na paměti, je, že inline funkce jsou cennou vlastností C++. Vhodné použití inline funkcí může poskytnout zvýšení výkonu, ale pokud jsou inline funkce používány libovolně, nemohou poskytnout lepší výsledky. Jinými slovy, neočekávejte lepší výkon programu. Nedělejte každou funkci inline. Je lepší udržovat inline funkce co nejmenší.