Funkcje inline
1. Co to jest funkcja inline?
Funkcja inline to funkcja, dla której sugerujemy kompilatorowi, aby zastąpił jej wywołania bezpośrednio kodem funkcji, czyli dokonał rozwinięcia funkcji (inlining).
Celem jest eliminacja narzutu wywołania funkcji:
- przekazywania argumentów,
- skoku do innego miejsca w pamięci,
- powrotu.
Funkcję inline oznaczamy słowem kluczowym:
2. Ważne: inline to tylko sugestia!
Współczesny kompilator NIE MUSI wstawić funkcji inline. Może to zrobić, ale może też zignorować słowo kluczowe, jeśli:
- funkcja jest zbyt duża,
- zbyt skomplikowana,
- zawiera pętle, warunki lub rekurencję,
- kompilator uzna, że inlining pogorszyłby wydajność.
C++ traktuje inline przede wszystkim jako dyrektywę linkera, a dopiero potem jako wskazówkę optymalizacyjną.
3. Co tak naprawdę oznacza inline?
Główna funkcja inline w C++
Umożliwia definiowanie tej samej funkcji w wielu plikach nagłówkowych bez błędu linkera "multiple definition".
Czyli:
- funkcja inline może być zdefiniowana w headerze (.h)
- i używana w wielu plikach
.cpp - bez naruszania zasady One Definition Rule (ODR).
To najważniejsze znaczenie inline we współczesnym C++.
4. Przykład funkcji inline
Po rozwinięciu kompilator mógłby wygenerować kod:
Bez żadnego wywołania funkcji.
5. Gdzie definiuje się funkcje inline?
Jeśli funkcja ma być inline, zwykle umieszcza się ją w pliku nagłówkowym:
Dlaczego? Bo tylko wtedy inlining ma sens i kompilator widzi definicję funkcji podczas kompilacji innych modułów.
6. Kiedy inline nie zadziała?
Kompilator zignoruje inlining, gdy funkcja:
- jest zbyt długa,
- zawiera pętle lub rekursję,
- jest zbyt skomplikowana,
- generuje zbyt dużo kodu,
- używana byłaby w wielu miejscach i inline spowodowałoby wzrost rozmiaru programu (code bloat).
Przykład, którego raczej nie wstawi:
7. Inline a funkcje rekurencyjne
Funkcje rekurencyjne nie mogą być sensownie inline, bo:
- rekurencja wymaga wywołania funkcji samej siebie,
- kompilator nie może jej w pełni rozwinąć.
Dlatego:
8. Inline a makra – różnice
Makro:
- wstawiane ślepo przez preprocesor
- brak kontroli typów
- możliwe błędy, efekty uboczne
Przykład błędu:
Funkcja inline:
- typy są sprawdzane
- brak efektów ubocznych
- zachowuje się jak normalna funkcja
Wniosek: Funkcje inline są bezpieczniejszą alternatywą dla makr.
9. Zalety funkcji inline
1. Eliminacja narzutu wywołań funkcji
Szybsze działanie w małych funkcjach.
2. Możliwość definiowania funkcji w plikach nagłówkowych
Bez błędów linkera.
3. Bezpieczeństwo typów
W przeciwieństwie do makr.
4. Możliwość optymalizacji przez kompilator
Nowoczesne kompilatory same decydują, czy inline się opłaca.
10. Wady i ograniczenia inline
1. Code bloat – puchnięcie kodu
Zbyt wiele wstawek inline zwiększa rozmiar programu.
2. Nie zawsze działa
To sugestia, nie nakaz.
3. Nie działa dobrze z funkcjami dużymi / skomplikowanymi
Kompilator to zignoruje.
4. Może utrudniać debugowanie
Bo krok po kroku debugger nie „wejdzie” do funkcji rozwiniętej inline.
11. inline a metody w klasach
Każda metoda zdefiniowana wewnątrz klasy jest automatycznie inline:
Jeśli nie chcesz inline, przenieś definicję do .cpp.
12. Podsumowanie
Funkcje inline w C++:
- eliminują narzut wywołania funkcji
- pozwalają definiować funkcje w plikach nagłówkowych
- są bezpieczniejsze niż makra
- są tylko SUGESTIĄ dla kompilatora
- nadużywanie może prowadzić do spuchnięcia kodu
- nie nadają się do dużych funkcji i rekurencji