2012-06-12 8 views
13

Sto lavorando nel linguaggio C e modificando il codice precedentemente scritto da qualcun altro. Sto lottando con alcune cose e sto cercando di capire il più possibile su quello che sta succedendo. Quindi, come la mia domanda ha affermato, qual è la differenza tra static inline void e void quando si crea una funzione? Mi scuso in anticipo per il post lungo, ma volevo che tu sapessi che ho fatto qualche ricerca, ma non capisco cosa ho trovato.Qual è la differenza tra vuoto statico e vuoto in linea?

ho trovato an explanation of static che mi confonde:

L'identificatore statica significa che la funzione non è possibile fare riferimento da altri file; ovvero, il nome non viene esportato dal linker.

Leggendo questo, presumo che il riferimento a una funzione sia diverso dal chiamare una funzione? Presumo che questa funzione sia chiamata da un altro file .c. In tal caso, che cosa fa riferimento a una funzione?

Attraverso lo stesso sito web, spiegano inline functions e non capisco cosa significhi.

La parola chiave __inline dice al compilatore di sostituire il codice all'interno la definizione di funzione per ogni istanza di una chiamata di funzione. Tuttavia, la sostituzione avviene solo a discrezione del compilatore. Per esempio , il compilatore non esegue la funzione inline se il suo indirizzo è preso o se è troppo grande per inline.

Huh ???

Qualsiasi aiuto è molto apprezzato e mi scuso ancora una volta per il post terribilmente lungo.

Di seguito è situato in file1.c (Usando nomi generici come io non credo che importa)

COMPLEX cNoiseSample; 
CGauss(&cNoiseSample, loopbackRadio->pState); 

Di seguito è situato in file2.c

static inline void CGauss(COMPLEX * pcGauss, P_OS_UNIFORM_RAND_STATE pState) 
{ 
    //code 
} 

risposta

12

static significa che non può essere referenziato da un'altra unità di compilazione (file sorgente). "Riferito" significa chiamato, o altrimenti indicato con il nome, ad es. assegnato a un puntatore di funzione.

inline è un suggerimento per il compilatore che il codice della funzione deve essere generato in linea nel punto in cui è chiamato, piuttosto che generato come una funzione separata da ramificare. Questo è normalmente fatto per ragioni di prestazioni. Per far fronte a citazione di Microsoft:

il compilatore non inline una funzione se è preso il suo indirizzo o se è troppo grande per linea.

Una funzione in linea non ha indirizzo, poiché non esiste come entità separata. Il suo codice si intreccia semplicemente con il codice da cui è chiamato. Quindi, se si prende l'indirizzo di una funzione (ad es. Per assegnarlo a un puntatore), il compilatore deve generarlo come una funzione reale e non in linea.

void significa che la funzione non restituisce alcun valore.


Dopo aver guardato il tuo esempio di codice, direi che c'è una definizione distinta di CGauss() da qualche parte, che viene chiamato da file1.c, mentre file2.c sta chiamando il proprio privato versione. O che, o file1.c è #include ing file2.c. Quale sarebbe brutto.

+0

anche 'inline' è necessario per applicare la regola a una definizione quando una funzione è definita in un'intestazione inclusa in diverse unità di compilazione (o almeno questo è il caso per C++, non conosco questo dettaglio esattamente in C, I immagino che sarà lo stesso) – rubenvb

+0

Beh, immagino di essere un po 'confuso di @ Graham-Borland. Lascia che ti mostri perché: COMPLEX cNoiseSample; CGauss (& cNoiseSample, loopbackRadio-> pState);/* Questo codice è chiamato in un punto in un file sorgente .c, e in un diverso file sorgente .c ho questo: */statico inline void CGauss (COMPLEX * pcGauss, P_OS_UNIFORM_RAND_STATE pState)/* Mi scuso per la cattiva formattazione nella casella dei commenti, non sapevo come fare altrimenti. */ – TZPike05

+0

Modifica la domanda, incolla lo snippet di codice qui. –

6

static significa solo qualcosa quando si dispone di più di un file sorgente. Si specifica che la funzione static o variabile non è possibile accedere dalle funzioni in un file diverso.

inline è un'ottimizzazione del compilatore che accelera il codice in alcuni casi. Ogni volta che si chiama una funzione, è associato a un sovraccarico. Quindi, ciò che il compilatore può fare è sbarazzarsi della funzione tutto insieme da copia + incolla (quasi) il codice inline.

Ecco un esempio di inline:

int dotproduct(int x1, int y1, int x2, int y2) { 
    return multiply(x1,x2)+multiply(y1,y2); 
} 

inline int multiply(int a, int b) { 
    return a*b; 
} 

il compilatore trasformare questo in:

int dotproduct(int x1, int y1, int x2, int y2) { 
    return x1*x2+y1*y2; 
} 

Se si vuole essere di fantasia, si può anche inline la funzione dotproduct;)

Si noti che la parola chiave inline è semplicemente una gomitata al compilatore per incorporare determinate funzioni. Potrebbe o meno farlo a seconda del proprio giudizio.

+0

Grazie a @tskuzzy, inline ha molto più senso ora. – TZPike05

0

statico significa semplicemente che essenzialmente la funzione di tutti gli effetti 'invisibili' esterno della sorgente che è definita.

linea askes al compilatore di substite essenzialmente il codice funzione chiamata direttamente alla fonte in ogni luogo la funzione viene chiamata al momento della compilazione (come una sostituzione della chiamata di funzione con il codice della funzione) - tuttavia, non è garantito che accada, suggerisce solo che il compilatore.

E 'più tecnico di quello e si rischia di ottenere una risposta di gran lunga migliore, ma in un linguaggio semplice questo è ciò che significano i termini.

2

La parola chiave static

Definire un mezzo statico funzione C (come dicono i documenti) che questa funzione può accedere solo dalla sorgente di file è definita nel. Il termine 'riferimento' in questo mezzo Sence o chiamando questa funzione o, ad esempio, assumendo un puntatore a funzione.

Inlining

Normalmente, quando si scrive una funzione in C, il compilatore genera il codice macchina per questa funzione:

foo: 
    /* some machine code */ 
    ret 

Ogni volta che si chiama questa funzione, il compilatore inserisce un'istruzione come

call <foo> 

nel codice macchina del chiamante, il che significa nient'altro che "saltare a pippo, e xecute ciò che trovi lì e quando incontri un'istruzione ret, torna in questa posizione. "

Al contrario, per le funzioni inline, il compilatore non genera una funzione separata foo(), ma inserisce il codice macchina per la funzione foo in ogni sito di chiamata. Quando si esegue questo codice, questo ha lo stesso effetto.

Quindi perché lo facciamo? Il codice di allineamento ha il vantaggio di salvare due salti (la chiamata e il rispettivo ret), il che rende il tuo codice un po 'più veloce. Come svantaggio, il tuo codice diventa più grande, perché inserisci il codice macchina su ogni sito di chiamata invece di avere solo una copia di una funzione chiamabile. Questo è il motivo per cui di solito solo inline piccole funzioni.

Inoltre, non è possibile utilizzare i puntatori di funzione per le funzioni inline e il debug diventa più difficile, poiché non è possibile impostare facilmente un punto di interruzione su una funzione in linea.

Pertanto, inlining è lasciato per il compilatore come opzione ottimizzazione e utilizzando una parola chiave come inline C++ s ', il tuo direttiva in linea , o di GCC __attribute ((in linea)), è solo dare al compilatore un suggerimento che inlining potrebbe valere la pena provare qui