2015-03-11 17 views
6

Ho letto parecchi post sull'utilizzo di static inline e inline durante la definizione di funzioni nei file di intestazione per l'accesso a più unità di traduzione. Sembra che inline sia il modo giusto per andare a causa del collegamento esterno.Dimensioni del codice: statico in linea rispetto a inline per funzioni definite nei file di intestazione

La mia domanda riguarda la dimensione del codice risultante come conseguenza dell'uso di inline identificatore al momento di definire le funzioni nei file .h:

  • è l'espansione codice generato da inline ancora minore rispetto a quello che sarebbe stato causato da static inline ?

  • Perché è necessaria una dichiarazione extern inline nel file .c corrispondente?

+0

Se si è preoccupati che le funzioni in linea potrebbero non essere in linea, è possibile che non si debbano inlustarle in primo luogo? Se non sei preoccupato, il compilatore inserirà comunque il codice e l'espansione del codice (che presumibilmente dovrebbe darti un vantaggio in termini di velocità; in caso contrario, non c'era alcun punto in cui inserire la funzione in primo luogo) dovrebbe essere accettabile. Non usare "in linea", volente o nolente. Usalo con cautela e giudizio e, in caso di dubbio, non usarlo. Vedi anche [È 'inline' senza' static' o 'extern' sempre utile in C99?] (Http://stackoverflow.com/questions/6312597) –

+0

Il motivo per cui si utilizza inline nel mio codice è fondamentalmente per consentire la definizione della funzione in il file di intestazione. Senza un inline/static inline, il compilatore si lamenta di più definizioni di simboli. Sono un po 'preoccupato per le dimensioni del codice, ma principalmente sto cercando di vedere quale beneficio mi dà più benefici, cioè meno espansione del codice, linea in linea o statica – thegeeklife

+0

@thegeeklife: Plain 'inline' (insieme a' extern inline' in qualche file '.c') sarebbe la migliore di queste due opzioni: significa che stai creando una singola funzione logica invece di molte, come delineato nella mia risposta. Dovresti considerare se hai davvero bisogno del codice nelle intestazioni. avere il codice nei file '.c', in più non rischi di spingere il compilatore in roba di inline che altrimenti potrebbe non avere (che sembra essere quello che ti preoccupa, come ha sottolineato Jonathan). il file in cui dovresti inserire 'extern inline' probabilmente sarebbe un posto logico dove inserire la definizione. – Ulfalizer

risposta

5

Potrebbe generare un codice più piccolo. Il motivo è che inline (al contrario di static inline) fornirà la funzione di collegamento esterno in modo che tutte le chiamate alla funzione da unità di traduzione diverse facciano riferimento alla stessa funzione logica. Con static inline, ciascuna unità di traduzione otterrà invece un'istanza unica della funzione, che potrebbe aumentare la dimensione del codice se il compilatore sceglie di non eseguire la linea. (È anche più pulito in codice per non avere più funzioni identiche.)

Il motivo per cui è necessario extern da qualche parte è perché rende il compilatore generare una definizione esterna della funzione che può essere chiamata da altre unità di traduzione. Senza extern, non viene generata alcuna istanza di questo tipo. Il caso no-extern differisce dal collegamento interno in quanto la definizione inline fornisce solo una "alternativa" alla definizione esterna della funzione. Una definizione esterna deve ancora esistere (ad esempio, alcune funzioni di traduzione devono utilizzare extern per generare una definizione esterna) e il compilatore è libero di usarlo al posto di esso.

Ecco alcuni standardese rilevanti (per C11: prescrittori 2011 §6.7.4 funzione, ¶7: ISO/IEC 9899):

Qualsiasi funzione con il collegamento interno può essere una funzione inline. Per una funzione con collegamento esterno, si applicano le seguenti restrizioni: Se una funzione è dichiarata con un identificatore di funzione inline, allora deve essere definita anche nella stessa unità di traduzione. Se tutte le dichiarazioni di ambito dei file per una funzione in un'unità di traduzione includono l'identificatore di funzione inline senza extern, la definizione in tale unità di traduzione è una definizione in linea . Una definizione in linea non fornisce una definizione esterna per la funzione e non vieta una definizione esterna in un'altra unità di traduzione. Una definizione in linea fornisce un'alternativa a una definizione esterna, che un traduttore può utilizzare per implementare qualsiasi chiamata alla funzione nella stessa unità di traduzione. Non è specificato se una chiamata alla funzione utilizza la definizione in linea o la definizione esterna. 140)

140) Da una definizione di linea è distinto dal corrispondente definizione esterna e da qualsiasi altro definizioni linea corrispondenti in altre unità di traduzione, tutti gli oggetti corrispondenti con statico stoccaggio durata sono distinti in ciascuna le definizioni.

A proposito, inline IMO spesso non vale la pena (come un suggerimento - il compilatore è ancora libero di non in linea) rispetto al semplicemente lasciando che il compilatore scegliere quando inline esclusivamente sulla propria. Per i compilatori moderni che supportano l'ottimizzazione , il compilatore può persino integrare le funzioni tra le unità di traduzione se si superano i contrassegni giusti (ad es., -flto in GCC).

+0

Risposta eccellente, ma quando si scrive 'inline', si è (di solito) ancora permettendo al compilatore di scegliere se integrare la funzione. –

+0

@DietrichEpp: intendevo esprimerlo, ma forse ho fallito. Lo esaminerò per vedere se può essere chiarito. – Ulfalizer

+0

Potrei aver appena letto il paragrafo in basso quando l'ho scritto. –

Problemi correlati