2009-06-01 14 views
17

Ho eseguito test di chiamate in linea in C++.Funzioni inline C++ tramite GCC - perché la CHIAMATA?

Thread model: win32 
gcc version 4.3.3 (4.3.3-tdm-1 mingw32) 

Stroustrup in The wirtes linguaggio di programmazione C++:

L'identificatore di linea è un suggerimento per il compilatore che dovrebbe tentare di generare il codice [...] in linea piuttosto che recante il codice per la funzione una volta e quindi chiamando il solito meccanismo di chiamata di funzione.

Tuttavia, ho scoperto che il codice generato non è semplicemente in linea. C'è un CALL instrction per la funzione isquare.

alt text http://i42.tinypic.com/8ys3f4.jpg

Perché succede questo? Come posso usare le funzioni inline allora?

EDIT: Le opzioni della riga di comando utilizzate:

**** Build of configuration Debug for project InlineCpp **** 

**** Internal Builder is used for build    **** 
g++ -O0 -g3 -Wall -c -fmessage-length=0 -osrc\InlineCpp.o ..\src\InlineCpp.cpp 
g++ -oInlineCpp.exe src\InlineCpp.o 
+1

Hai controllato quale codice viene generato quando aumenti il ​​livello di ottimizzazione? Inoltre, prova ad aggiungere il parametro '-finline-functions' durante la compilazione del codice – Christoph

+2

Si prega di postare le opzioni della riga di comando utilizzate con gcc per compilare il codice. (Se non stai usando una delle funzioni -O3 o -finline allora gcc ignorando "in linea" non mi sorprende). – timday

+3

il problema è -O0 hai i tuoi flag del compilatore, che significa ** no ** ottimizzazioni. Passa a -O2 e sarà inline bene. –

risposta

22

non c'è modo generico C++ per forzare il compilatore per creare funzioni inline. Nota la parola "suggerimento" nel testo che hai citato - il compilatore non è obbligato ad ascoltarti.

Se davvero, devi assolutamente rendere qualcosa in linea, avrai bisogno di una parola chiave specifica del compilatore, oppure dovrai usare le macro invece delle funzioni.

MODIFICA: njsf fornisce la corretta parola chiave gcc nella sua risposta.

0

Se in linea è fino al compilatore. È libero di ignorare l'avviso inline. Alcuni compilatori hanno una parola chiave specifica (come __forceinline in VC++), ma anche con tale parola chiave le chiamate virtuali alle funzioni dei membri virtuali non saranno in linea.

3

È un suggerimento e il compilatore può scegliere di ignorare il suggerimento. Penso di aver letto un po 'dove quel GCC generalmente lo ignora. Ricordo che c'era una bandiera ma non funziona ancora nel 100% dei casi. (Non ho ancora trovato un collegamento).

Flag: -finline-funzioni è attivata a livello di ottimizzazione -O3.

+3

Credo che la principale differenza che gcc paga per "in linea" sia che significa che la funzione può essere fino a 600 istruzioni di grandi dimensioni e viene ancora sottolineata, mentre le funzioni non dichiarate in linea per l'autoallineamento con -finline-funzioni devono essere inferiori a 300 Istruzioni. Puoi fare un pasticcio con tutti questi numeri e altro usando --param per aggiustare le cose con nomi come max-inline-insns-auto (ma hai bisogno di un buon motivo per: i valori di default sono validi). Cambiare la differenza tra i numeri per esplicita e autoallineamento significa che puoi effettivamente fare in linea avere più o meno un effetto. – timday

+0

Questo è molto interessante. Grazie. –

47

Come menzionato da Michael Kohne, la parola chiave inline è sempre un suggerimento e GCC nel caso della funzione ha deciso di non inserirlo.

Poiché si utilizza Gcc, è possibile forzare in linea con __attribute ((sempre_inline)).

Esempio:

/* Prototype. */ 
inline void foo (const char) __attribute__((always_inline)); 

Fonte: GCC inline docs

+0

upvoted per il gcc-fu –

+5

Sì, ma se l'interrogante sparisce e inizia a incollare __attribute __ ((sempre_inline)); su tutte le sue funzioni invece di compilare solo con -O3, abbiamo fallito. – timday

+2

concordato. Immagino di essere ancora un ottimista e credo che molte persone abbiano un po 'di buon senso ;-) – njsf

8

stai guardando una build di debug (ottimizzazioni disabilitata)? Generalmente i compilatori disabilitano l'inlining nei build di "debug" perché rendono più difficile il debugging.

In ogni caso, lo inline specificato è in effetti un suggerimento . Il compilatore non è obbligato a incorporare la funzione. Ci sono una serie di motivi per cui qualsiasi compilatore potrebbe decidere di ignorare un suggerimento in linea:

  • Un compilatore potrebbe essere semplice, e non supportano inlining
  • Un compilatore può utilizzare un algoritmo interno per decidere su cosa in linea e ignorare i suggerimenti.
    (a volte, il compilatore può fare un lavoro migliore di quanto si possa fare a scegliere cosa linea, soprattutto in architetture complesse come IA64)
  • Un compilatore potrebbe utilizzare i propri euristica per decidere che, nonostante il suggerimento, inlining non migliorerà le prestazioni
4

Inline non è altro che un suggerimento al compilatore che, se è possibile integrare questa funzione, il compilatore dovrebbe prendere in considerazione l'idea di farlo. Alcune funzioni verranno automaticamente allineate perché sono così semplici e altre funzioni suggerite da suggeriscono perché non lo sono perché sono troppo complesse.

Inoltre, ho notato che si sta facendo una build di debug. In realtà non lo so, ma è possibile che il compilatore disabiliti l'inline per le build di debug perché rende le cose difficili per il debugger ...

0

Ho affrontato problemi simili e ho scoperto che funziona solo se la funzione inline è scritta in un file di intestazione.

+0

Perché il downvote? sybreon è corretto, nel caso in cui la funzione inline sia chiamata da un altro modulo ... – bitsmack