2009-09-18 20 views
14

In C++, fanno i metodi ottiene solo inline se sono dichiarati esplicitamente inline (o definiti in un file di intestazione), o sono compilatori autorizzati ai metodi in linea come meglio credono?Quando compilano il codice C++ in linea?

+2

nota: inline è solo accennare al compilatore. Il compilatore non è obbligato a collegarlo. –

+0

@ Martin York: Sfortunatamente hai ragione. E nel 99,9% dei casi è meglio lasciare decidere al compilatore nell'ultima istanza. Ma in alcuni casi (programmi critici per le prestazioni come l'elaborazione delle immagini, ecc.) Sarebbe bello avere un interruttore di forzatura in linea definitivo. Ma posso capire i programmatori del compilatore. Perché non appena questo interruttore esisterebbe molti lo userebbero in molti casi inappropriati, non importa quanto insistentemente la documentazione avverta di usarlo solo in rari casi ... – mmmmmmmm

+1

Più precisamente, 'inline' ha un significato diverso nel codice C/C++ rispetto quello usato per descrivere l'ottimizzazione. Nel codice C/C++, 'inline' significa semplicemente che possono esistere più definizioni di una funzione e che il linker dovrebbe unirle di nuovo insieme. Fa * not * significa che le chiamate a quella funzione dovrebbero essere inline. Sono due concetti completamente separati. – jalf

risposta

21

Sì, il compilatore può inline codice, anche se non è esplicitamente dichiarato come inline.

In sostanza, fino a quando la semantica non sono cambiati, il compilatore può praticamente fare qualsiasi cosa che vuole il codice generato. Lo standard non impone nulla di speciale sul codice generato.

+2

Dato che il compilatore fa tutto per noi, perché mai abbiamo bisogno di un suggerimento in linea? –

+1

@lz_prgmr: Beh, oltre al punto sottile menzionato da UncleBens in basso, penso che non lo facciamo. È importante notare che i compilatori * non * erano così intelligenti fin dall'inizio e siamo piuttosto bloccati con le vecchie funzionalità del linguaggio. –

+0

Grazie, penso che la spiegazione abbia un senso: per ragioni storiche ... –

4

Se non mi sbaglio, quando le ottimizzazioni sono accesi, il compilatore inline qualsiasi routine o metodo adatto.

+0

"Attivazione delle ottimizzazioni" non è un termine standard. Stai descrivendo le implementazioni reali, chi ha quell'interruttore. In tal caso non è necessario l'ipotetico _may_: il compilatore _will_ funzioni appropriate integrate. – MSalters

+0

@MSalters, hai ragione. –

5

compilatori potrebbero inline qualsiasi funzione o potrebbero non inline esso. Sono autorizzati a utilizzare la decorazione inline come suggerimento per questa decisione, ma possono anche ignorarlo.

Si noti inoltre che le funzioni dei membri della classe hanno una decorazione implicita inline se sono definite proprio nella definizione della classe.

4

compilatori possono ignorare la vostra dichiarazione di linea. Fondamentalmente è usato dal compilatore come suggerimento per decidere se farlo o no. I compilatori non sono obbligati a incorporare qualcosa che è contrassegnato in linea o non in linea a qualcosa che non lo è. Fondamentalmente sei in balia del tuo compilatore e del livello di ottimizzazione che scegli.

3

testo da IBM informazioni Centrale,

Usando lo specificatore inline è solo una suggerimento al compilatore che un'espansione linea può essere eseguita; il compilatore è libero di ignorare il suggerimento .

C Lingua qualsiasi funzione, con l'eccezione del principale, possono essere dichiarati o definito come in linea con la funzione di identificatore inline . Le variabili locali statiche non possono essere definite definite all'interno del corpo di una funzione in linea .

C++ le funzioni implementate all'interno di una dichiarazione di classe sono definite automaticamente in linea. Regolare C++ funzioni e le funzioni membro dichiarate all'esterno di una dichiarazione di classe , ad eccezione di principale, può essere dichiarato o definite come linea con la funzione inline specificatore. I valori locali statici e stringhe letterali definiti all'interno del corpo di una funzione in linea vengono considerati come lo stesso oggetto tra le unità di traduzione;

0

La parola chiave inline è solo una richiesta al compilatore. Il compilatore si riserva il diritto di rendere o non rendere una funzione in linea. Uno dei fattori principali che spinge la decisione del compilatore è la semplicità del codice (non molti loop)

funzioni gli sono dichiarate inline di default. (Il compilatore decide anche qui)

Queste non sono regole dure e veloci .Varia in base alle implementazioni del compilatore.

Se qualcuno conosce altri fattori coinvolti, si prega di inviare.

0

Il compilatore può incorporare ciò che vuole nel caso in cui l'inlining non violi la semantica del codice e possa raggiungere il codice funzione. Può anche essere in linea in modo selettivo - fare inline quando ritiene che sia una buona idea e non in linea quando non ritiene che sia una buona idea o quando violerebbe la semantica del codice.

Alcuni compilatori possono eseguire l'inlining anche se la funzione si trova in un'altra unità di traduzione: si tratta della generazione del codice link-time.

I casi tipici di inlining che violano la semantica del codice sono chiamate virtuali e passaggio di un indirizzo di funzione in un'altra funzione o memorizzazione di esso.

1

Il compilatore ottimizza come vuole, a meno che non si specchi il contrario.

+0

Haha il compilatore è un uomo –

27

Il linea parola chiave in realtà solo dice il linker (o dice al compilatore a dire il linker) che più definizioni identiche della stessa funzione non sono un errore. Ne avrai bisogno se vuoi definire una funzione in un'intestazione, o riceverai errori di "definizione multipla" dal linker, se l'intestazione è inclusa in più di una unità di compilazione.

Le motivazioni alla base della scelta di in linea poiché la parola chiave sembra essere che l'unica ragione per cui si vorrebbe definire una funzione (non modello) in un'intestazione è che potrebbe essere inline dal compilatore. Il compilatore non può in linea una chiamata di funzione, a meno che non abbia la definizione completa. Se la funzione non è definita nell'intestazione, il compilatore ha solo la dichiarazione e non può inline la funzione anche se lo desidera.

Al giorno d'oggi, ho sentito, non è solo il compilatore che ottimizza il codice, ma anche il linker può farlo. Un linker potrebbe (se non lo fanno già) chiamate di funzione in linea anche se la funzione non è stata definita nella stessa unità di compilazione.

E probabilmente non è una buona idea definire funzioni più grandi di una singola riga nell'intestazione (male per il tempo di compilazione, e se la grande funzione è in linea, potrebbe portare a prestazioni gonfie e peggiori).

+0

+1 per indicare il "doppio significato" di 'inline' – peterchen

+1

Questo è l'aspetto veramente importante di inline. –

2

La documentazione del compilatore dovrebbe dirvi poiché dipende dall'implementazione. Ad esempio, GCC in base al suo manuale non inserisce mai alcun codice a meno che non venga applicata l'ottimizzazione.

Se il compilatore non inline il codice, il linea parola chiave avrà lo stesso effetto di statica, e ogni unità di compilazione che chiama il codice avrà la propria copia. Un linker intelligente può ridurli a una singola copia.

0

Alcune delle situazioni in cui l'espansione in linea potrebbe non funzionare sono:

  1. Per le funzioni che ritornano valori, se un loop, un interruttore o un goto esiste
  2. per la funzione valori non ritorno, se un ritorno uscite di dichiarazioni;
  3. Se le funzioni contengono variabili statiche
  4. Se le funzioni inline sono ricorsivi.

L'espansione in linea consente di eseguire un programma più rapidamente perché il sovraccarico di una chiamata di funzione e di un'istruzione di ritorno viene eliminato. Tuttavia, rende il programma più memoria perché le istruzioni che definiscono le funzioni inline sono riprodotte in ogni punto in cui viene chiamata la funzione. Quindi, diventa necessario un compromesso.

(come indicato in uno dei miei libri OOP)

Problemi correlati