2013-07-06 8 views
10

Cosa succede se definisco la mia funzione nel mio file .h comeCosa succede con una funzione inline esterna?

extern int returnaint(void); 

, definisco nel file .c correlata come

inline int returnaint(void) { 
    return 1; 
} 

e includere l'intestazione in un altro file .c e l'uso la funzione? Quando compilo le cose separatamente, creando un file oggetto per ogni file .c e quindi collegandole, è inclusa la funzione inline o cosa succede?

So che il compilatore può ignorare inline, ma cosa succede se non lo ignora in questo caso?

+2

quindi si ottiene un errore di linker. –

+2

@ H2CO3, non ci sarà mai un errore del linker. L'unità di compilazione con la definizione 'inline' visualizza anche una dichiarazione' extern', quindi un simbolo deve essere emesso. Per favore vedi la mia risposta. –

+0

@JensGustedt Grazie, upvoted. –

risposta

20

Dopo aver aggiunto inline alla definizione della funzione nel file .c è semplicemente superfluo.

  • tuo unità di compilazione del file .c vede un extern dichiarazione (senza inline) e una definizione inline. In questo modo emette il simbolo per la funzione nel file oggetto.

  • Tutte le altre unità di compilazione visualizzano solo una dichiarazione extern e quindi possono utilizzare la funzione senza problemi se si collega l'eseguibile finale con l'altro file .o.

In realtà, hai appena sbagliato strada. Questa funzione deve essere utilizzata per avere la definizione inline nel file .h, visibile a tutti. Questa definizione della funzione agisce solo come una dichiarazione del simbolo, proprio come lo sarebbe extern, ma non lo definisce.

Una dichiarazione extern in un solo file .c (unità di compilazione) assicura quindi che il simbolo sia definito lì.

La terminologia è un po 'di confusione, la inlinedefinizione in qualità di dichiarazione del simbolo, e il externdichiarazione in qualità di definizione di esso

+1

Bel punto. Penso che dovrei spostare le mie funzioni inline sull'intestazione! :-) – musicmatze

+0

L'aggiunta in linea nell'unità di traduzione che definisce la funzione ha un effetto. Il risultato probabile è che gli usi di detta funzione in questa unità di compilazione saranno in linea. –

+0

@ UweKleine-König, no. Il compilatore è libero di fare qualsiasi cosa. Se la definizione della funzione è visibile, il compilatore può o meno scegliere di inline, a condizione che rispetti la regola "as-if". Nulla cambia aggiungendo 'inline' a quella definizione. –

4

Non verrà compilato. Da C11 (ISO/IEC 9899: 2011) §6.7.4 specificatori funzione (enfasi aggiunta):

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 in linea, deve essere definita anche nella stessa unità di traduzione. Se tutte le dichiarazioni dello scope di file per una funzione in un'unità di traduzione includono la 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.

L'altro .c file viene solo la dichiarazione della funzione inline dalla testata, ma non la definizione, quindi è contro il dominio in grassetto.

EDIT:

Come @Jens Gustedt sottolinea, la mia spiegazione precedente è sbagliato, perché nella domanda del PO, la funzione è dichiarata come non in linea nel file di intestazione:

extern int returnaint(void); 

Quindi l'altro file .c lo tratterà come una normale funzione.

+8

risposta sbagliata. gli altri file '.c' non vedono' inline' la dichiarazione nel '.h' ha solo' extern' non 'inline'. –