Jeśli zdefiniujemy funkcję składową w samej definicji klasy, czy jest ona traktowana inline, czy jest to po prostu żądanie kompilatora, które może zignorować.Funkcje wbudowane w C++
Odpowiedz
Tak, funkcje zdefiniowane w treści klasy są domyślnie inline
.
(Podobnie jak w przypadku innych funkcji zadeklarowanych jako inline
nie oznacza to, że kompilator musi wykonywać liniowe rozszerzanie w miejscach, w których funkcja jest wywoływana, tylko zezwala na dozwolone rozluźnienia "jednej reguły definicji" w połączeniu z wymaganiem że definicja musi być zawarta we wszystkich jednostkach tłumaczeniowych, w których funkcja jest używana.)
Jest to żądanie do kompilatora, które może zignorować.
Nie, jest to wymagane. Jeśli funkcja jest zdefiniowana w treści klasy, musi być traktowana tak, jakby została zadeklarowana jako "inline". –
podobnie jak każde żądanie "inline", które kompilator może zignorować. – shoosh
Ponieważ można go zignorować, a większość kompilatorów będzie wstawiać tam, gdzie jest to właściwe, nawet gdy nie zażąda się go, jest to dość bezużyteczna wskazówka. – marr75
Jest ona traktowana przez kompilator jako żądanie do wstawienia - które może zignorować. Istnieją pewne idiomy do definiowania niektórych funkcji w nagłówku (np. Puste destruktory wirtualne) i niektóre niezbędne definicje nagłówków (funkcje szablonów), ale inne niż te zobacz GotW #33, aby uzyskać więcej informacji.
Niektórzy zauważyli, że kompilator może nawet wstawiać funkcje, o które nigdy nie prosiłeś, ale nie jestem pewien, czy to by uniemożliwiło zadanie wywołania funkcji.
Zależy od kompilatora. Generalnie inline to podpowiedź, która niewiele robi. Myślę, że większość kompilatorów ukierunkowanych na platformy osadzone słucha podpowiedzi ściślej, a to jest naprawdę jedyna przestrzeń, w której po starannym zaprojektowaniu może być lepiej niż kompilator. – marr75
Jest rzeczywiście wstawiony - ale dowolne wbudowane żądanie może zostać zignorowane przez kompilator.
Norma ISO C++ 2003 mówi
7.1.2/2 Deklaracja funkcji (8.3.5, 9.3, 11.4) z inline specyfikatorem deklaruje inline funkcję. Inline specyfikator wskazuje realizacji że rolki podstawienie treść funkcji w miejscu połączenia ma być korzystne zwykłe wywołanie funkcji
mechanizmu. Implementacja nie jest wymagana w celu dokonania tego zastępowania w miejscu połączenia; jednakże, nawet jeśli to podstawienie zostanie pominięte, pozostałe zasady dla funkcji wbudowanych zdefiniowanych jako według 7.1.2 będą nadal respektowane.7.1.2/3 Funkcja zdefiniowana w definicji klasy jest wbudowaną funkcją
. Wewnętrzny specyfikator nie może pojawić się w deklaracji funkcji zakresu blokowego .7.1.2/4 Funkcja inline określa się w każdej jednostce tłumaczeniowej w
który jest używany i ma dokładnie taką samą definicję w każdym
przypadku (3.2). [Uwaga: wywołanie funkcji inline może zostać napotkane przed jej definicją w jednostce tłumaczeniowej . ] Jeżeli funkcja z zewnętrznym połączeniem jest zadeklarowana jako w jednej jednostce przeliczeniowej, to musi ona być deklarowana we wszystkich jednostkach tłumaczeniowych , w której występuje ; diagnostyka nie jest wymagana.Funkcja inline z zewnętrznym łącznikiem musi mieć ten sam adres w jednostkach tłumaczeniowych pod numerem . Statyczna zmienna lokalna w zewnętrznej funkcji wbudowanej zawsze odnosi się do tego samego obiektu . Literał ciągu znaków w zewnętrznej funkcji inline jest tym samym obiektem w różnych jednostkach translacji.
Jest to najbardziej przydatna odpowiedź, ale jest również myląca, ogólnie rzecz biorąc, główny nurt kompilatorów koncentruje się na "elemencie implementacji nie wymaga tego elementu zastępującego" standardu. – marr75
Są dwie rzeczy, które nie powinny być zalicza razem:
- Jak zaznaczyć funkcję jako inline: zdefiniować go inline przed podpisaniem lub zdefiniować ją w punkcie deklaracji;
- Co kompilator będzie obsługiwał takie wbudowane znakowanie: niezależnie od tego, jak oznaczono funkcję jako wbudowaną, będzie traktowane jako żądanie przez kompilator.
Jak podano przez innych, metoda zdefiniowana w klasie jest automatycznie żądana w linii. Warto zrozumieć, dlaczego.
Załóżmy, że tak nie było. Będziesz musiał wygenerować kod dla takiej funkcji, a wszędzie, gdzie jest ona wywoływana, skok do instrukcji podprogramu będzie musiał odwoływać się do lokalizacji za pośrednictwem łącznika.
class A {
public:
void f() { ... your code ... }
};
Za każdym razem ten kod jest widziany, jeśli nie jest inline, kompilator może przyjmować tylko musi zostać wygenerowany, więc byłoby wygenerować symbol. Załóżmy, że to było tak:
A__f_v:
Jeśli symbol były globalne, a następnie, jeśli stało się to ten kod klasy wiele razy w różnych modułach, to miałby wielokrotnie zdefiniowany symbol błędu w czasie połączenia. Więc nie może być globalne. Zamiast tego jest to plik lokalny.
Wyobraź sobie, że umieściłeś powyższy plik nagłówkowy w wielu modułach. W każdym z nich wygeneruje lokalną kopię tego kodu. Co jest lepsze niż brak kompilacji, ale dostajesz wiele kopii kodu, kiedy naprawdę potrzebujesz tylko jednego.
Prowadzi to do następującego wniosku: jeśli twój kompilator nie będzie wbudowywał funkcji, znacznie lepiej jest go zadeklarować gdzieś na raz i nie żądać, aby był on wstawiony.
Niestety to, co jest i nie jest wbudowane, nie jest przenośne. Jest określony przez autora kompilatora. Dobrą zasadą jest zawsze tworzyć każdą linijkę, w szczególności wszystkie funkcje, które same nazywają funkcję, wbudowane, gdy usuniesz obciążenie. Wszystko poniżej trzech linii liniowego kodu jest prawie na pewno w porządku. Ale jeśli masz pętlę w kodzie, pytanie brzmi, czy kompilator zezwoli na to w linii, a bardziej do rzeczy, ile korzyści zobaczyłbyś, nawet gdyby zrobił to, co chcesz.
rozważyć ten kod inline:
inline int add(int a, int b) { return a + b; }
To nie tylko prawie tak małe jak prototyp będzie w kodzie źródłowym, ale asemblera generowane przez kod inline jest mniejszy niż wezwanie do rutynowych byłoby . Więc ten kod jest mniejszy i szybszy.
I, jeśli zdarzy ci się być przechodzącej w stałych:
int c= add(5,4);
To rozwiązany w czasie kompilacji i nie ma kodu.
W gcc, niedawno zauważyłem, że nawet jeśli nie mam kodu inline, czy to lokalny do pliku, będą one sneakily inline tak. Dopiero jeśli zadeklaruję funkcję w osobnym module źródłowym, nie zoptymalizuję połączenia.
Na drugim końcu spektrum, załóżmy poprosić inline na kawałku 1000 linii kodu. Nawet jeśli kompilator jest na tyle głupi, aby przejść wraz z nim, jedyną rzeczą, jaką można zapisać to samo wezwanie, a koszt jest to, że za każdym razem to nazwać, kompilator musi przenieść cały ten kod. Jeśli tak nazwać razy N Kod twój kod rośnie o rozmiar rutyny * n. Zatem wszystko, co jest większe niż 10 linii, nie jest warte podkreślenia, z wyjątkiem specjalnego przypadku, w którym jest on nazywany bardzo małą liczbą razy. Przykładem może być metoda prywatna zwana tylko przez 2 inne.
Jeśli żądać inline metodę zawierającą pętlę, tylko ma sens, jeśli często wykonuje niewielką liczbę razy. Ale pomyśl o pętli, która iteruje milion razy. Nawet jeśli kod jest wstawiony, procent czasu spędzonego na rozmowie jest niewielki. Więc jeśli masz metod z pętli w nim, które wydają się być większe i tak, te są warte usunięcie z pliku nagłówka, ponieważ a) będą miały tendencję zostać odrzucony jako inline przez kompilator i b), nawet jeśli zostały one wstawiane są na ogół nie zapewni żadnych korzyści.
Po prostu rozwaliłeś mój umysł. Jeśli zdefiniuję funkcję w normalny sposób (z definicją tutaj i implementacją tam na dole), a ja wstawię słowo kluczowe z przodu (definicji implementacji? Obojga?), To kompilator rozważy jego wstawienie? A to jest lepsze? Moją główną obawą związaną z funkcjami wbudowanymi jest to, że są brzydkie i powodują, że linia jest długa. Czy mówisz, że mogę mieć normalnie seksowne i łatwe do odczytania funkcje wbudowane ... i nie tylko to, ale czy w ten sposób zaznaczę małe funkcje? Mam nadzieję, że jesteś aktywnym użytkownikiem i odpowiesz na ten komentarz. – Ziggy
Jeśli zdefiniujesz funkcję za pomocą prototypu, z implementacją w tym samym pliku nagłówkowym zaznaczonym w wierszu, zostanie ona wstawiona jako wbudowana. Jeśli implementacja znajduje się w innym pliku, kompilator nie może go wstawić. To nie jest czytnik myśli, nie wie, jaki kod wygenerować. Osobiście nie mam nic przeciwko dodatkowemu kodowi w nagłówku, zamiast pisać go dwa razy, ale na pewno możesz to zrobić, jeśli wolisz. – Dov
@ziggy, jeśli dobrze rozumiem twoje pytanie, tak, jeśli twoja funkcja jest krótka, zdefiniowanie jej w wierszu w pliku nagłówkowym może być ogromną wygraną w czasie runtime, jednocześnie nieco spowalniając czas kompilacji, a także wymagając wszelkich symboli wymienionych w zdefiniować funkcję inline. Oznacza to, że jeśli twój kod śródliniowy odnosi się do innych obiektów, twój nagłówek może zawierać inne nagłówki. Tak więc istnieje potencjalne duże koszty w czasie rekompilacji. Ale dla średniej metody (getter/setter, obliczanie czegoś ze zmiennymi prywatnymi), inlineing to ogromna wygrana. – Dov
- 1. Funkcje wbudowane
- 2. Funkcje wbudowane w kompilację debugowania (Visual C++ 2008)
- 3. Czy lambdas jest wbudowane jak funkcje w C++?
- 4. Czy funkcje asynchroniczne mogą być wbudowane?
- 5. Czy LLVM konwertuje metody Objective-C na funkcje wbudowane?
- 6. Dlaczego niektóre "funkcje" wbudowane w python faktycznie są typami?
- 7. Nieudokumentowane wbudowane funkcje renderowania plików PDF w systemie Windows?
- 8. Co właściwie robi ustawienie wbudowane Xcode 5 "Nieużywane funkcje"?
- 9. Wbudowane w Clang nie tak wbudowane?
- 10. funkcje ukrywanie w C
- 11. Co się stanie, jeśli funkcje rekursywne będą wstawiane jako wbudowane?
- 12. Tablica PHP kopiuje określone klucze, wbudowane funkcje? Zagnieżdżona wydajność pętli?
- 13. Czy wbudowane funkcje wirtualne są naprawdę pozbawione sensu?
- 14. Funkcje wbudowane Pythona nie są tak naprawdę funkcjami, prawda?
- 15. Dziedziczenie i wbudowane?
- 16. tagi wbudowane w angularjs
- 17. Sztuczne anonimowych funkcje C
- 18. C++ lotne funkcje członkowskie
- 19. Programowanie wbudowane ... bardzo początek
- 20. Wszystkie wbudowane atrybuty .Net
- 21. Czy funkcje inline C++ GCC nie zawierają słowa kluczowego "inline"?
- 22. obiektywne metody C Klasa vs C Funkcje
- 23. Arkusze kalkulacyjne Google: jak uzyskać pierwszy (N-ty) wiersz/kolumnę z zakresu? (wbudowane funkcje)
- 24. Czy funkcje alertów i potwierdzeń są wbudowane w JavaScript, czy też są częścią DOM?
- 25. Wiele parametrów w jednym parametrze (funkcje) w C/C++
- 26. Warunkowo wbudowane w admin Django?
- 27. C++: funkcje zewnętrzne i inline
- 28. Funkcje wielkości i bezpieczeństwo wątków w C++
- 29. wyłącza funkcje C++ 11 w vs2013
- 30. Wywiad pytanie o funkcje wirtualne w C++
Zobacz także http://stackoverflow.com/questions/908830/isnt-cs-inline-totally-optional/910686#910686 –