2013-02-07 10 views
15

Powiedzmy, że mam funkcję w moim programie i gdzieś w moim kodzie, funkcja ta jest wywoływana przez wskaźnik funkcji. Co się stanie, jeśli kompilator zainicjuje tę funkcję, lub czy kompilator zda sobie sprawę, że istnieje wskaźnik funkcji przypisany do tej funkcji, a zatem unika go zaznaczania.Co się stanie, jeśli kompilator wstawi funkcję, która jest wywoływana przez wskaźnik funkcji

+2

Zobacz Herb Sutter's [Inline Redux] (http://www.drdobbs.com/inline-redux/184403879). –

Odpowiedz

12

Po pobraniu wskaźnika do funkcji kompilator wygeneruje treść poza linią dla funkcji. Nadal możliwe jest wstawianie funkcji w innych witrynach połączeń.

Należy pamiętać, że funkcja oznaczona inline musi mieć definicję dostępną we wszystkich JT, które się do niej odnoszą, a definicje te muszą być identyczne. Oznacza to, że możesz całkowicie zainicjować funkcję w niektórych witrynach z telefonami i utrzymywać ją poza linią.

+0

Co się stanie, jeśli definicje nie są identyczne (np. Jakiś kod ifdef'd), a linker otrzyma wiele wersji funkcji? "Inline" jest prawdopodobnie postrzegany przez linker jako słaby symbol, a otrzymujesz pierwszy, który pojawia się? –

+6

@NicholasWilson, który byłby nieprawidłowym programem. –

+2

@NicholasWilson, który byłby naruszeniem zasady jednej definicji, i jest jawnie nazywany jako bez określonego zachowania. –

4

Cóż, na pewno zadziała. Nie rozumiem, w jaki sposób inline mogłoby temu zapobiec. Masz tylko kod, który wywołuje funkcję bezpośrednio, i może być tam wstawiony, i masz jakiś kod, który wywołuje go za pomocą wskaźnika funkcji, tak jak zwykła funkcja.

3

Nie ma powodu, dla którego używanie wskaźnika funkcji powinno zapobiegać wstawianiu. Inlining odbywa się indywidualnie dla każdego przypadku i może istnieć równolegle do zwykłej funkcji. Tak więc funkcja może być zaznaczona w jednym miejscu i wywołana w innym.

Kompilator będzie zatem wstawał tam, gdzie może i nadal będzie wywoływał funkcję wywoływaną dla wskaźnika funkcji.

2

Nie tylko inline kompilator „inne wywołania funkcji”, ale może nawet inline połączenia poprzez wskaźników funkcji, jeśli rozumie wystarczająco dużo o których funkcja jest rzeczywiście używany, coś takiego:

typedef void (*funcptr)(); 

void somefunc() 
{ 
    ... do stuff here ... 
} 

void indirection(funcptr *f) 
{ 
    f(); 
} 

void call_with_ptr() 
{ 
    funcptr f = somefunc(); 
    for(int i = 0; i < 100; i++) 
    { 
     indirection(f); 
    } 
} 

Miałem kod podobny do tego, i zwrócił na bok i wywołał somefunc() bezpośrednie połączenie bez użycia wskaźnika funkcji.

Ale oczywiście zakłada to, że kompilator może dowiedzieć się, która funkcja jest wywoływana z kodu - co jest w tym przypadku oczywiste, ale jeśli w grę wchodzą decyzje wykonawcze, może tego nie robić.

Powiązane problemy