2011-07-05 13 views
6

Studiuję funkcje wbudowane w C++ i przeszedłem do rozdziału dotyczącego ograniczeń jego użycia. Mówi:Czasy, gdy funkcja inline nie może być używana

Kompilator nie może również wykonywać inline jeśli adres funkcji pochodzi pośrednio lub wyraźnie.

Czy ktoś może mi wytłumaczyć, być może na przykładzie jakiegoś rodzaju, co to dokładnie oznacza?

+3

Och, nienawidzę tego nowego bezpłatnego systemu dociekań. Co do diabła było nie tak z tym pytaniem, ludzie? –

+0

Z ciekawości, jaką książkę zawiera to stwierdzenie? –

+1

+1 do walki z anonimowym drive-by downvoter –

Odpowiedz

5

Istnieją dwa nieco odrębne decyzje dotyczące kompilator robi funkcja inline:

  • , czy dana funkcja jest wywołanie inlined;
  • , czy istnieje nielinearna wersja funkcji.

Pierwsza jest określana przez kompilator osobno dla każdego przypadku, jeśli w tym momencie możliwe jest wstawianie. Nie będzie to możliwe, jeśli funkcja jest wirtualna lub wywołana przez wskaźnik funkcji i nie może ustalić w czasie kompilacji, która funkcja ma zostać wywołana. Nie będzie możliwe, jeśli definicja nie będzie dostępna dla kompilatora, być może dlatego, że jest zdefiniowana w innej jednostce tłumaczeniowej, a kompilator nie wykonuje "pełnej optymalizacji programu". Decyzja może, ale nie musi, być zależna od tego, czy funkcja jest zadeklarowana jako inline, i innych czynników, takich jak jej rozmiar i jak często jest wywoływana.

Druga zależy od tego, czy wymagana jest wersja nielinearna. Będzie to wymagane, jeśli żadne połączenie z nim nie zostanie zainicjowane. Będzie również (jak na swoją ofertę) wymagane, jeśli cokolwiek potrzebuje adresu funkcji, ponieważ wtedy musi mieć adres. Może się to zdarzyć bezpośrednio (na przykład poprzez przypisanie adresu do wskaźnika funkcji) lub pośrednio (na przykład funkcje wirtualne będą potrzebowały przechowywania ich gdzieś w celu sprawdzenia w środowisku wykonawczym zgodnie z typem dynamicznym obiektu).

Istnienie nieliniowej wersji nie uniemożliwi zainicjowania żadnego konkretnego wywołania tej funkcji, chociaż możliwe, że wpłynie ona na decyzję kompilatora, szczególnie jeśli jest skonfigurowany do optymalizacji pod kątem rozmiaru kodu.

Podsumowując, Twoja oferta jest uproszczona i nie do końca dokładna; kompilator może nadal "wykonywać inlining", jeśli adres jest zajęty, po prostu nie można pominąć wersji nielinearnej.

+0

Dzięki, twój przykład przypisania adresu do wskaźnika funkcji naprawdę pomaga zrozumieć, co oznacza to stwierdzenie. –

4

To po prostu źle: na zdolność do wywoływania funkcji nie ma wpływu obliczanie 2 + 2 lub pobieranie adresu funkcji gdzieś.

Którą książkę lub artykuł czytasz?

Z drugiej strony, jeśli adres zostanie zajęty, może być praktycznie niemożliwe usunięcie oddzielnej funkcji kodu maszynowego.

Cheers & HTH.,

+0

http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter09_009.html –

+0

Och, "Myślenie w C++" autorstwa Bruce'a Eckela. Cóż, wiele błędów w tej książce pojawiło się na przestrzeni lat. Ale o ile wiem, Bruce nigdy niczego nie poprawił. Więc bądź ostrożny. Pisze dobre rzeczy dla nowicjuszy, ale pisze też bezsensowne i niepoprawne rzeczy. Tak jak tutaj. –

+0

Kiedy wspominasz o błędach, w jednym pytaniu w książce należy utworzyć klasę w pliku nagłówkowym, który zawiera wbudowaną funkcję o nazwie print. W rozwiązaniu do książki ma jednak tylko deklarację print() w nagłówku i jego definicję w pliku sepearate. Czy mam rację mówiąc, że jest to również błąd i jeśli chcę funkcji inline w pliku nagłówkowym, to musi ona zawierać zarówno definicję, jak i deklarację, że jest funkcją inline? –

6

Można oznaczyć żadnego funkcji jako inline. Nawet funkcja wirtualna, nawet funkcja rekursywna, nawet bardzo długa funkcja, nawet jeśli adres jest zajęty. Główną różnicą pomiędzy funkcją inline i inline jest to, że definicja pierwszej musi występować w każdej jednostce tłumaczeniowej (aka pliku źródłowego), w której jest używana (dlatego funkcje inline są zwykle zdefiniowane w pliku .h), podczas gdy ten ostatni należy zdefiniować tylko jeden raz. Możesz użyć funkcji inline w każdy sposób, który możesz użyć nieinstancji inline.

Faktyczna część podliniowa zależy od kompilatora. Może zignorować Twoją prośbę, jeśli na przykład twoja funkcja jest rekurencyjna lub zbyt długa. Z drugiej strony kompilator może wybrać funkcję, która nie została faktycznie oznaczona jako wbudowana.

+1

w nowszych wersjach GCC, istnieje opcja dla pełnej optymalizacji programu - która AFAIK, będzie wymagać umieszczenia dowolnego kodu, który masz nadzieję, być w nagłówku, zbędny ... – Nim

Powiązane problemy