2012-04-11 17 views
25

Qual è la differenza tra utilizzando la parola chiave inline prima di una funzione e solo dichiarando l'intera funzione nell'intestazione?Inline parola chiave vs definizione intestazione

così ...

int whatever() { return 4; } 

vs

.h:

inline int whatever(); 

cpp:

inline int myClass::whatever() 
{ 
    return 4; 
} 

per quella materia, che cosa fa questo:

inline int whatever() { return 4; } 

risposta

10

senzainline, è probabile che finirà con più esportato simboli, se la funzione è dichiarato al namespace globale o portata (risultati in errori del linker).

tuttavia, per una classe (come nel tuo esempio), la maggior parte dei compilatori dichiara implicitamente il metodo come inline (-fno-default-inline disabiliterà quell'impostazione predefinita su GCC).

se si dichiara una funzione come inline, il compilatore può aspettarsi di vedere la sua definizione nella traduzione. pertanto, dovresti prenotare per le volte in cui la definizione è visibile.

a un livello superiore: una definizione nella dichiarazione di classe è spesso visibile a più traduzioni. questo può comportare un'ottimizzazione migliore e può comportare tempi di compilazione maggiori.

a meno che l'ottimizzazione della mano e la compilazione veloce siano entrambi importanti, è inusuale utilizzare la parola chiave in una dichiarazione di classe in questi giorni.

2

Questa domanda spiega molto su funzioni inline What does __inline__ mean ? (anche se si trattava di linea parola chiave.)

In sostanza, non ha nulla a che fare con l'intestazione. Dichiarare l'intera funzione nell'intestazione cambia semplicemente quale file sorgente ha l'origine della funzione. La parola chiave Inline modifica dove la funzione compilata risultante verrà inserita nella propria posizione, in modo che ogni chiamata andrà lì, o al posto di ogni chiamata (migliore per le prestazioni). Tuttavia, i compilatori a volte scelgono quali funzioni o metodi rendere inline per se stessi e le parole chiave sono semplicemente suggerimenti per il compilatore. Anche le funzioni che non sono state specificate in linea possono essere scelte dal compilatore per diventare in linea, se ciò offre prestazioni migliori.

1

Se si collegano più oggetti in un file eseguibile, in genere dovrebbe essere presente un solo oggetto che contiene la definizione della funzione. Per int whatever() { return 4; } - qualsiasi unità di traduzione utilizzata per produrre un oggetto conterrà una definizione (ad esempio codice eseguibile) per la funzione whatever. Il linker non saprà a quale indirizzare i chiamanti. Se viene fornito inline, il codice eseguibile può essere o meno inserito nei siti di chiamata, ma se non è il linker è autorizzato a presupporre che tutte le definizioni siano uguali e selezionarne una arbitrariamente per indirizzare i chiamanti. Se in qualche modo le definizioni non erano le stesse, allora è considerata TUA colpa e si ottiene un comportamento indefinito.Per utilizzare inline, la definizione deve essere nota al momento della compilazione della chiamata, quindi l'idea di inserire una dichiarazione inline in un'intestazione e la definizione inline in un file .cpp funzionerà solo se tutti i chiamanti si troveranno più tardi nello stesso file .cpp file - in generale è rotto e ci si aspetterebbe che la definizione della funzione inline (nominalmente) appaia nell'intestazione che la dichiara (o che ci sia una definizione singola senza dichiarazione preventiva).

28

Ci sono diversi aspetti:

lingua

  • Quando una funzione è contrassegnata con la parola chiave inline, quindi la sua definizione dovrebbe essere disponibile nel TU o il programma è malformati.
  • Qualsiasi funzione definita direttamente nella definizione della classe viene contrassegnata in modo implicito inline.
  • Una funzione contrassegnata con inline (implicitamente o esplicitamente) può essere definita in più TU (rispettando l'ODR), mentre non è il caso per le funzioni regolari.
  • Le funzioni di modello (non completamente specializzate) hanno lo stesso trattamento di inline.

comportamento del compilatore

  • Una funzione contrassegnata inline sarà emesso come un simbolo debole in ogni file oggetto dove è necessario, questo può aumentare la loro dimensione (guardare in alto modello di gonfiare).
  • Mentre il compilatore allinea effettivamente la chiamata (ad esempio, copia/incolla il codice nel punto di utilizzo anziché eseguire una normale chiamata di funzione) è interamente a discrezione del compilatore. La presenza della parola chiave può o meno influenzare la decisione, ma è, nel migliore dei casi, un suggerimento .

comportamento Linker

  • simboli deboli vengono fuse insieme per avere una singola occorrenza nella libreria finale. Un buon linker potrebbe verificare che le definizioni multiple consentano, ma questo non è richiesto.
+6

Cosa intendi per "TU" e "ODR"? – WiSaGaN

+4

@WiSaGaN: TU = Unità di traduzione: approssimativamente, il file sorgente preelaborato. ODR = Una regola di definizione: è necessario che tutte le definizioni di una funzione/classe siano identiche, a livello di carattere, attraverso le TU. –

+0

A livello di carattere o livello token? – fredoverflow

9

Lo scopo inline è quello di consentire una funzione da definire in più di un'unità di traduzione, che è necessario per alcuni compilatori possano all'inline ovunque viene utilizzato. Dovrebbe essere utilizzato ogni volta che si definisce una funzione in un file di intestazione, sebbene sia possibile ometterlo durante la definizione di un modello o una funzione all'interno di una definizione di classe.

Definirlo in una intestazione senza inline è una pessima idea; se includi l'intestazione da più di un'unità di traduzione, interrompi la regola della definizione unica; il tuo codice probabilmente non si collegherà e potrebbe mostrare un comportamento indefinito se lo fa.

Dichiararlo in un'intestazione con inline ma definirlo in un file sorgente è anche una pessima idea; la definizione deve essere disponibile in qualsiasi unità di traduzione che la utilizza, ma definendola in un file sorgente è disponibile solo in una unità di traduzione. Se un altro file sorgente include l'intestazione e tenta di chiamare la funzione, il tuo programma non è valido.