Domanda

Se io definisco una funzione non membro in un'intestazione, sarà sempre essere inline dal compilatore, o fa il compilatore scegliere in base alle sue euristiche? So che __inline è solo un accenno, è lo stesso con funzioni di intestazioni?

È stato utile?

Soluzione

Ricordate che compreso qualcosa da un colpo di testa non è diverso da semplicemente digitando direttamente nel file di origine. Quindi, essendo in un colpo di testa non fa alcuna differenza per quanto riguarda il compilatore è interessato; non è mai sapeva che era lì.

Quindi, quando si definisce una funzione in un file di intestazione, e si include il file di intestazione in un file, è come appena digitato la funzione direttamente nel file. Così ora la domanda è: "fa il compilatore sceglie di cose in linea sulla base di euristiche?"

La risposta è "dipende dal compilatore". Lo standard non fornisce alcuna garanzia su ciò che viene inline o meno. Detto questo, qualsiasi compilatore moderno sarà estremamente intelligente su ciò che inline, probabilmente con l'euristica.

Comunque, arriviamo ad un punto interessante. Immaginate di avere una funzione in un colpo di testa e di includere tale intestazione in più file di origine. Si avrà quindi più definizioni della funzione, attraverso unità di traduzione, e questo viola la regola una definizione. Ergo, si otterrà errori di compilazione. (L'errore di linker è di solito qualcosa sulla falsariga di: "Errore, la funzione X già definito nel y"). Che cosa si può fare è utilizzare la parola chiave inline e non si è più violano l'ODR

A proposito __inline non è standard. Contrariamente al tuo post, di solito è un estensione del compilatore, che forze inlining, non accenna esso. inline è la parola chiave di serie, che è stato originariamente destinato a accenno alla inlining. Come dici tu, i compilatori più moderni ignorano completamente a questo proposito ed è unico scopo è quello di dare al giorno d'oggi le cose collegamento interno.

Altri suggerimenti

C ++ FAQ Lite :

  

Non importa come si designa una funzione   come linea, si tratta di una richiesta che il   compilatore è permesso di ignorare: essa   potrebbe inline-espandere alcuni, tutti o nessuno   delle chiamate a una funzione inline.

sceglierà sulla base di euristiche. Assicurati si dichiara come in linea esplicitamente altrimenti si può ottenere un errore di simbolo di collegamento duplicato se si include l'intestazione in più di un'unità di compilazione.

Se Definisci una funzione con collegamento esterno in un file di intestazione e comprendono in più di un'unità di traduzione, si otterrà errore di compilazione (più precisamente: linker erorr) per violazione di One Definizione Regola (ODR). Quindi la risposta è "no": la definizione di una funzione in un file di intestazione non sarà presa dal compilatore come un suggerimento a inlining e non si scuserà dall'osservazione dei requisiti di ODR. Non solo queste funzioni non sono garantiti per essere inline, ma molto probabilmente il programma non sarà nemmeno la compilazione.

Al fine di definire una funzione in un file di intestazione e farla franca si deve dare sia esso il collegamento interno (dichiararla static, e finire con funzione separata per ogni unità di traduzione), o esplicitamente dichiararla inline.

Per quanto riguarda le euristiche ... compilatori moderni considererà normalmente praticamente qualsiasi funzione per inlining (mediante l'applicazione di euristiche), indipendentemente da dove si è definito e se si dichiara esplicitamente inline oppure no.

Non c'è magia sulle funzioni nelle intestazioni. Il compilatore non sa nemmeno se una funzione è definita in un'intestazione o meno. (Dal momento che le intestazioni siano effettivamente basta copiare / incollare nel file di origine, è possibile definire in un colpo di testa, ma il compilatore appena lo vede come parte della unità di traduzione)

Ci sono anche due diversi significati di "in linea" di essere a conoscenza:

Una funzione può essere inline come definito dalla standard C ++: Ciò avviene anteponendo la funzione della parola inline, o se non é una funzione membro, definendo in posto all'interno la definizione della classe.

L'effetto di questo è di

  • informare il linker che possa incontrare la definizione di funzione in più file, e dovrebbe semplicemente in silenzio fonderli insieme invece di generare un errore
  • rendere più facile per il compilatore per eseguire la messa in linea ottimizzazione .

L'inlining ottimizzazione invece, è semplicemente l'atto di sostituzione di una chiamata di funzione dal corpo della funzione chiamata, i quali mezzi quali l'ottimizzazione è effettivamente applicata ai siti di chiamata, non funzioni . Una funzione potrebbe essere chiamata normalmente alcuni luoghi, ma inline altrove. Una chiamata di funzione è inline quando il compilatore si sente come se, ed è meglio separare concettualmente del tutto dal primo significato di "in linea".

Il compilatore applicherà l'ottimizzazione inlining se, quando e dove ci si sente come esso. Esso utilizza un sacco di euristica per questo. funzioni più piccole hanno maggiori probabilità di essere inline. Se si stabilisce che un sito specifica chiamata sta per essere eseguito sufficientemente spesso, è più probabile che sia inline. In ultima analisi, l'euristica che usi si basano su "Will It migliorare o prestazioni degrado". Ed è in genere un giudice migliore di questo che gli esseri umani, in modo che non dovrebbe davvero bisogno di sapere quali euristica precisa che utilizza. Inlining troppo servirà solo a danneggiare le prestazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top