• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Inline a klasy

Cloud VPS
0 głosów
954 wizyt
pytanie zadane 30 czerwca 2016 w C i C++ przez Avernis Nałogowiec (27,400 p.)
Słyszałem że niektóre kompilatory mają automatycznie inline w funkcjach w klasach. Chciałbym wiedzieć jakie, i ewentualnie jeśli visual c++ jak ma to jak to wyłączyć?

1 odpowiedź

0 głosów
odpowiedź 30 czerwca 2016 przez niezalogowany
Ale inline jest dobre
komentarz 30 czerwca 2016 przez Avernis Nałogowiec (27,400 p.)
Mam takie pytanie upewniające się. Czy jest funkcje będzie "zasługiwać" na inline, a ja go nie zdefiniuję, to kompilator zrobi to za mnie, tak?
komentarz 30 czerwca 2016 przez Sebastian Fojcik Nałogowiec (43,040 p.)

Owszem. Jakaś prosta funkcja, której nie opłaca się wywoływać (np. w pętli) zostanie przeniesiona w miejsce wywołania. Przykładowo:

bool wieksze( int a, int b )
{
    return a > b;
}

int main()
{
    for( int i = 0; i <= 10; i++ )
    {
        wieksze( i, 5 );
    }
}

Tutaj jest pętla. Wywołanie funkcji oznacza chwilowe zawieszenie main() i przeniesienie wykonywania programu do innego miejsca. To zajmuje czas. Pętla zwalnia, program zwalnia. Zatem najlepiej byłoby przenieść kod do pętli i tak na 98% zrobi kompilator pomimo nieumieszczenia specyfikatora inline.

komentarz 1 lipca 2016 przez Avernis Nałogowiec (27,400 p.)
A inline umieszcza w czasie kompilacji, czy w czasie działania programu? Oraz jak to się odnosi do funkcji którą raz się opłaca dawać inline, a raz nie i do konstruktorów i destruktorów.
komentarz 1 lipca 2016 przez Sebastian Fojcik Nałogowiec (43,040 p.)
edycja 1 lipca 2016 przez Sebastian Fojcik

inline obsługuje kompilator. Niemożliwym jest zatem, aby to umieszczanie w miejscu wywołania miało miejsce w czasie działania programu. Działanie programu to wykonywanie jego kodu. Nie można wtedy nic mieszać w jego strukturze. Kompilator działa tylko w czasie kompilacji i to właśnie wtedy wywołania podmieniane są na ciało funkcji (identycznie jak przy #define).

Nie istnieje jedna funkcja, którą raz się opłaca dawać inline, a raz nie. Jeśli jest to krótka funkcja (jak w moim przykładzie powyżej), która będzie wywoływana tysiące razy, to może się okazać, że kod generowany z obsługą wywołania funkcji i powrotem zajmie więcej pamięci niż wklejenie jej ciała 1000 razy gdzieś w kodzie. Jeśli funkcja jest spora, to nigdy nie opłaca Ci się dawać jej inline. Jeśli wywołujesz tysiące razy jakąś dużą funkcję, to również. Trudno. Program zwolni o 0,0001 s. Musisz to przeboleć.

Pamiętaj też, że wypisywanie czegokolwiek na ekran, czy to przy po mocy cout <<, czy printf(), to również są wywołania funkcji i przeskoki w inne miejsca. Musisz zdać sobie sprawę, że prawie wszystko co robisz w kodzie, to wywołanie jakiejś funkcji. Nawet zwykłe utworzenie string:

string napis = "Ala";

Wywołujesz funkcję z argumentem const char* "Ala"

Konstruktory i destruktory tak samo jak inne funkcje mogą stać się inline. Choć o tym najpewniej zadecyduje sam kompilator. Więc nie ma z tym problemu.

Ciekawszym tematem są funkcje wirtualne, które również mogą być inline. I nie, to nie jest przejęzyczenie. Nie rujnuje to zasad działania polimorfizmu, bo kompilator sobie z tym radzi w ciekawy sposób. Nie chcę się tutaj rozwodzić za bardzo, ale w skrócie napiszę: Kompilator rozpoznaje kiedy wywoływana jest funkcja rodzica, a kiedy potomka i dzięki temu jest w stanie w każde miejsce wywołania funkcji rodzica, wstawić ciało tej funkcji. W pozostałych sytuacjach tego nie robi, więc funkcja jest niejako... pół-inline :-)

komentarz 1 lipca 2016 przez adrian17 Mentor (354,120 p.)

Nie istnieje jedna funkcja, którą raz się opłaca dawać inline, a raz nie.

Z punktu widzenia kompilatora, jak najbardziej istnieje. Taki f(x) może być nie inline'owaną funkcją, ale już z f(0) kompilator może więcej wywnioskować i być może wykonać inlining.

kod generowany z obsługą wywołania funkcji i powrotem zajmie więcej pamięci niż wklejenie jej ciała 1000 razy gdzieś w kodzie.

Niemożliwe, bo różnica powinna być widoczna tylko na stosie. Do tego musiała by być silnie rekurencyjna. W ogóle nie powinieneś się przejmować zużyciem stosu, póki nie dociągniesz do stack overflow.

Jeśli funkcja jest spora, to nigdy nie opłaca Ci się dawać jej inline.

Jeśli wywołujesz ją w dokładnie jednym miejscu w kodzie, to wtedy najbardziej się opłaca, niezależnie od wielkości.

Konstruktory i destruktory tak samo jak inne funkcje mogą stać się inline. Choć o tym najpewniej zadecyduje sam kompilator. Więc nie ma z tym problemu.

Mieszasz "inline" o którego obecności decyduje user (i czasem reguły języka) oraz "inlining", który leży całkowicie w gestii kompilatora (póki nie użyje się rzeczy w style __declspec((noinline)) ). Z roku na rok te terminy stają się coraz bardziej odległe.

Podobne pytania

0 głosów
1 odpowiedź 1,910 wizyt
pytanie zadane 28 lutego 2016 w HTML i CSS przez niezalogowany
0 głosów
0 odpowiedzi 109 wizyt
0 głosów
2 odpowiedzi 194 wizyt
pytanie zadane 10 grudnia 2015 w C i C++ przez Avernis Nałogowiec (27,400 p.)

93,459 zapytań

142,453 odpowiedzi

322,722 komentarzy

62,837 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Kursy INF.02 i INF.03
...