2012-01-16 21 views
10

Ho una funzione static inline definita in un file H, e ad un certo punto in un file C, sto assegnando un puntatore alla funzione, qualcosa di simile:C: Puntatore inline funzione

foo.h :

static inline void frobnicate(void) { 
    // frobs something. 
} 

foo.c

#include "foo.h" 

void execute(void (*func)(void)) { 
    func(); 
} 

void blahBlahBlah(void) { 
    execute(frobnicate); 
} 

bar.c

#include "foo.h" 
// ... 
frobnicate(); 

Quindi penso che ciò che accadrà qui è che il compilatore inline la chiamata a frobnicate da bar.c, ma in foo.c, in realtà dovrà creare una funzione per implementare frobnicate, in modo che possa avere un funzionamento puntatore ad esso.

Qualcuno può confermare se la mia comprensione è accurata e correggermi altrimenti?

+2

* È possibile confermarlo, leggendo il codice generato. Non penso che ci sia un modo specifico in cui * deve * funzionare. Non sarei sorpreso se il compilatore dicesse "qualcuno vuole l'indirizzo di questo, quindi cerchiamo di non inserirlo, quindi". – unwind

+7

Ricorda che 'inline' è solo una _suggestion_ per il compilatore –

risposta

10

inline è uno dei termini impropri dello standard C. Il suo significato principale è quello di essere in grado di inserire la definizione di una funzione in un file di intestazione senza dover affrontare problemi di "definizione multipla" al momento del collegamento.

Il modo ufficiale in C99 e C11 di fare ciò che si vuole raggiungere è quello di avere la definizione inline nel file di intestazione, senza il static. Poiché è necessario anche il simbolo da emettere, è necessario indicare al compilatore in quale unità di compilazione dovrebbe essere. Tale istanziazione può essere eseguita con una dichiarazione in questo file .c in cui si omette la parola chiave inline.

Naturalmente è possibile utilizzare il file .c in cui è effettivamente necessario il simbolo.

+0

Se la definizione in linea si trova nel file di intestazione senza 'static', allora non avrei più definizioni dello stesso nome (la funzione inline) quando provo a collegarmi? – brianmearns

+0

Si avranno problemi di collegamento. O renderlo 'static inline', e rischiare più definizioni, o rinunciare in linea.Puoi anche creare un wrapper, che si troverà in un file C e non sarà in linea, e prenderà un puntatore ad esso (nessun risultato in termini di prestazioni, perché la funzione reale sarà incorporata nel wrapper). – ugoren

+0

@bmearns, con un compilatore C99 compatibile non avrete problemi di collegamento. Questo è esattamente il senso della parola chiave 'inline'. http://gustedt.wordpress.com/2010/11/29/myth-and-reality-about-inline-in-c99/ –

7

Sì, hai ragione. Quando si prende il puntatore sulla funzione, il compilatore deve creare una versione "autonoma" in cui il codice può essere chiamato come una funzione normale.

Il vantaggio di incorporare una funzione è che il codice chiamante non deve essere creato e qualsiasi altra ottimizzazione può essere applicata per integrare sia la funzione chiamante che quella in linea. Ma quando è necessario effettuare una chiamata regolare alla funzione (come quando si prende l'indirizzo per chiamarlo quest'ultimo), tali ottimizzazioni non sono più possibili.

+2

Questo può essere vero per molti compilatori, ma non riesco a immaginare perché un compilatore sarebbe richiesto di farlo. L'esempio dell'OP potrebbe essere abbastanza facilmente in linea anche nel caso del puntatore della funzione. –

+0

'inline' è una raccomandazione. Se il compilatore non è in linea, non lo farà, e se non può, potrebbe ancora decidere di non farlo (e potrebbe essere in linea anche senza la parola chiave 'inline'). I puntatori di funzione generalmente impediscono l'allineamento, anche se in questo caso il compilatore può capire che non lo fa (o potrebbe non preoccuparsi). – ugoren

+0

Sì, in questo caso sarebbe possibile integrare la funzione. Presumo che questa fosse una versione semplificata del problema. Ma hai ragione. – Governa

Problemi correlati