Quando compilano il codice C ++ in linea?

In C ++, i metodi vengono solo inline se dichiarati esplicitamente in inline (o definiti in un file di intestazione) oppure i compilatori sono autorizzati a utilizzare i metodi in linea come meglio credono?

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

Fondamentalmente, finché la semantica non viene modificata, il compilatore può praticamente fare qualsiasi cosa voglia al codice generato. Lo standard non impone nulla di speciale sul codice generato.

La parola chiave inline dice solo al linker (o dice al compilatore di dire al 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.

La logica alla base della scelta in linea come 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).

I compilatori potrebbero inline qualsiasi funzione o non lo potrebbero in linea. Sono autorizzati a usare la decorazione in inline come suggerimento per questa decisione, ma possono anche ignorarlo.

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

I compilatori possono ignorare la tua dichiarazione inline. 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.

Se non sbaglio, quando le ottimizzazioni sono triggerste, il compilatore integrerà qualsiasi routine o metodo appropriato.

Testo dal centro informazioni IBM ,

L’uso dello specificatore in linea è solo un suggerimento per il compilatore che può essere eseguita un’espansione in linea; il compilatore è libero di ignorare il suggerimento.

C Language Qualsiasi funzione, ad eccezione di main, può essere dichiarata o definita come inline con l’identificatore di funzione inline. Le variabili locali statiche non possono essere definite all’interno del corpo di una funzione inline.

Le funzioni C ++ implementate all’interno di una dichiarazione di class vengono definite automaticamente in linea. Le normali funzioni C ++ e le funzioni membro dichiarate al di fuori di una dichiarazione di class, con l’eccezione di main, possono essere dichiarate o definite come inline con l’identificatore di funzione inline. I locals statici e i letterali stringa definiti all’interno del corpo di una funzione inline vengono considerati come lo stesso object tra le unità di traduzione;

La documentazione del tuo compilatore dovrebbe dirti che 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 incorpora il codice, la parola chiave inline avrà lo stesso effetto di static e ogni unità di compilazione che chiama il codice avrà una sua copia. Un linker intelligente può ridurli a una singola copia.

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

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 guida la decisione del compilatore è la semplicità del codice (non molti loop)

Le funzioni membro sono dichiarate in linea per impostazione predefinita (anche il compilatore decide 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.

Il compilatore può incorporare ciò che vuole nel caso in cui l’inlining non violi la semantica del codice e possa raggiungere il codice della 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 la funzione di inlining anche se la funzione si trova in un’altra unità di traduzione: si tratta della generazione del codice link-time.

Casi tipici di quando l’inlining violerebbe la semantica del codice sono chiamate virtuali e il passaggio di un indirizzo di funzione in un’altra funzione o l’archiviazione.

Alcune delle situazioni in cui l’espansione in linea potrebbe NON funzionare sono:

  1. Per le funzioni che restituiscono valori, se esiste un loop, un interruttore o un goto
  2. Per la funzione che non restituisce valori, se esce una dichiarazione di ritorno;
  3. Se le funzioni contengono variabili statiche
  4. Se le funzioni inline sono ricorsive.

L’espansione in linea fa correre un programma più veloce perché il sovraccarico di una chiamata di funzione e di una dichiarazione 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)