2011-05-11 19 views
57

perché dovrei fare qualcosa di simile:C++ funzione inline?

inline double square (double x) { return x*x;} 

invece di

double square (double x) { return x*x;} 

C'è una differenza?

+0

possibile duplicato del [funzioni inline vs preprocessore macro] (http://stackoverflow.com/questions/1137575/inline-functions-vs-preprocessor-macros) –

+0

In realtà ci sono un sacco di doppioni e near-dupes: http://stackoverflow.com/search?q=c%2B%2B+inline. Alcune risposte sono migliori di altre, alcune affermano erroneamente che la parola chiave "in linea" fa sì che la funzione sia in linea in tutti i siti di chiamata e così via. Quello non può essere il dupe più vicino. –

risposta

73

Il primo (utilizzando inline) consente di inserire tale funzione in un file di intestazione, in cui può essere incluso in più file di origine. L'utilizzo di inline rende l'identificatore nello scope del file allo stesso modo di dichiararlo static. Senza utilizzare inline, si otterrebbe un errore di definizione di più simboli dal linker.

Naturalmente, questo è in aggiunta al suggerimento per il compilatore che la funzione deve essere compilata in linea in cui viene utilizzata (evitando una funzione di overhead di chiamata). Il compilatore non è tenuto ad agire in base al suggerimento inline.

+1

Ho pensato che lo scopo di inline fosse che il compilatore "espandesse" il contenuto della funzione in cui è chiamato, quindi non ci sarà la ricerca vtable (o l'istruzione salterà alla funzione a livello della CPU). –

+0

Il tuo primo punto è un [utile] effetto collaterale della destinazione d'uso? –

+0

@Ian Fleeton: è davvero un effetto collaterale; se un identificatore in linea non aveva scope di file, sarebbe impossibile inserire una definizione di funzione inline in un file di intestazione. –

20

Su un compilatore moderno non c'è molta differenza. Può essere inline senza lo inline e potrebbe essere non essere inlineato con il inline.

+0

Ha senso, sono passato dall'esperienza di riferimento e di 10 anni. –

27

Sì, c'è una differenza. https://isocpp.org/wiki/faq/inline-functions.

Quando si specifica che una funzione è in linea si sta inducendo il compilatore a inserire il codice del metodo nel punto in cui viene chiamato.

void myfunc() { 
    square(2); 
} 

è identico al

void myfunc() { 
    2 * 2; 
} 

Chiamata di una funzione è buona per il codice di chiarezza, ma quando tale funzione è chiamato lo stato locale deve essere spinto alla pila, un nuovo stato locale è configurato per il metodo, e quando è fatto lo stato precedente deve essere spuntato. Questo è un sacco di spese generali.

Ora, se si aumenta il livello di ottimizzazione, il compilatore prenderà decisioni come loop di srotolamento o funzioni di inlining. Il compilatore è ancora libero di ignorare l'istruzione inline.

+2

Penso che con gcc puoi usare il flag di compilazione '-Winline' per avvisare quando una funzione non sarà inline. E potresti combinarlo con '-Werror' se sei un massacratore. – patmanpato

2

La funzione inline, se il compilatore è conforme, includerà la funzione inline nel codice in cui è stato chiamato come se non fosse stata richiamata alcuna funzione (come se si fosse inserita la logica nella funzione di chiamata) ed evitare la chiamata di funzione spese generali.

+6

Il compilatore non deve in linea la funzione se non lo desidera, anche se la parola chiave inline è specificata. – Marlon

+1

@Alex Marlon non ha detto che il compilatore ** non avrebbe ** incorporato la funzione, ma semplicemente che ** non deve **. Queste sono cose molto diverse. – anthropomorphic

2

inline funziona bene con il concetto di astrazione procedurale:

inline double square (double x) { return x*x;} 

int squareTwice(double x) { 
    double first = square(x); 
    double second = square(x); 
    return first * second; 
} 
Quanto sopra

è fondamentalmente simile al seguente:

int squareTwice(double x) { 
    double first = x*x; 
    double second = x*x; 
    return first * second; 
} 

Ciò avviene perché quando il compilatore inline-espande una funzione chiamata, il codice della funzione viene inserito nello stream del codice del chiamante; pertanto, potrebbe essere più semplice estrapolare proceduralmente il secondo esempio al primo esempio.

L'astrazione procedurale consente di suddividere una routine in subroutine più piccole che sono molto più facili da leggere (anche se questa può essere una scelta di stile).

5

Da Wikipedia: la funzione Inline è una funzione su cui è stato richiesto al compilatore di eseguire l'espansione in linea. In altre parole, il programmatore ha richiesto che il compilatore inserisca il corpo completo della funzione in ogni posto in cui viene chiamata la funzione, piuttosto che generare codice per chiamare la funzione nel punto in cui è definita. I compilatori non sono obbligati a rispettare questa richiesta.

http://en.wikipedia.org/wiki/Inline_function

Problemi correlati