Qual è la differenza tra la funzione “statico” e “statica in linea”?

IMO entrambi rendono la funzione solo per un ambito dell’unità di traduzione.

Qual è la differenza tra la funzione “statico” e “statica in linea“?

Perché dovrebbe essere inserito in inline in un file di intestazione, non nel file .c ?

inline indica al compilatore di tentare di incorporare il contenuto della funzione nel codice chiamante anziché eseguire una chiamata effettiva.

Per piccole funzioni chiamate frequentemente che possono fare una grande differenza di prestazioni.

Tuttavia, questo è solo un “suggerimento”, e il compilatore può ignorarlo, e la maggior parte dei compilatori proveranno a “in linea” anche quando la parola chiave non viene utilizzata, come parte delle ottimizzazioni, dove è ansible.

per esempio:

 static int Inc(int i) {return i+1}; .... // some code int i; .... // some more code for (i=0; i<999999; i = Inc(i)) {/*do something here*/}; 

Questo ciclo stretto eseguirà una chiamata di funzione a ogni iterazione e il contenuto della funzione è in realtà significativamente inferiore al codice che il compilatore deve inserire per eseguire la chiamata. inline istruirà essenzialmente il compilatore per convertire il codice sopra in un equivalente di:

  int i; .... for (i=0; i<999999; i = i+1) { /* do something here */}; 

Salto della chiamata della funzione effettiva e ritorno

Ovviamente questo è un esempio per mostrare il punto, non un vero pezzo di codice.

static riferisce allo scopo. In C significa che la funzione / variabile può essere utilizzata solo all'interno della stessa unità di traduzione.

Per impostazione predefinita, una definizione in linea è valida solo nell’unità di traduzione corrente.

Se la class di archiviazione è extern , l’identificatore ha un collegamento esterno e la definizione in linea fornisce anche la definizione esterna.

Se la class di archiviazione è static , l’identificatore ha il collegamento interno e la definizione in linea è invisibile in altre unità di traduzione.

Se la class di archiviazione non è specificata, la definizione in linea è visibile solo nell’unità di traduzione corrente, ma l’identificatore ha ancora il collegamento esterno e una definizione esterna deve essere fornita in un’unità di traduzione diversa. Il compilatore è libero di utilizzare la definizione inline o esterna se la funzione viene chiamata all’interno dell’unità di traduzione corrente.

Dato che il compilatore è libero di incorporare (e non in linea) qualsiasi funzione la cui definizione è visibile nell’unità di traduzione corrente (e, grazie alle ottimizzazioni in tempo di collegamento, anche in unità di traduzione diverse, sebbene lo standard C non rappresenti realmente che), per la maggior parte degli scopi pratici, non c’è differenza tra static definizioni di funzioni static inline static e static inline .

Lo specificatore in inline (come la class di archiviazione register ) è solo un suggerimento per il compilatore e il compilatore è libero di ignorarlo completamente. I compilatori non ottimizzanti conformi agli standard devono solo onorare i loro effetti collaterali e l’ottimizzazione dei compilatori eseguirà queste ottimizzazioni con o senza suggerimenti espliciti.

inline e register non sono inutili, poiché istruiscono il compilatore a generare errori quando il programmatore scrive codice che renderebbe imansible l’ottimizzazione: una definizione inline esterna non può fare riferimento agli identificatori con il collegamento interno (poiché questi non sarebbero disponibili in un altro unità di traduzione) o definire variabili locali modificabili con durata dell’archiviazione statica (poiché queste non condividono lo stato tra le unità di traduzione) e non è ansible prendere gli indirizzi delle variabili qualificate del register .

Personalmente, utilizzo la convenzione per contrassegnare static definizioni di funzioni static all’interno di intestazioni anche inline , in quanto il motivo principale per cui inseriscono le definizioni di funzione nei file di intestazione è renderle invisibili.

In generale, utilizzo solo la funzione static inline e static const definizioni di oggetti static const oltre alle dichiarazioni extern all’interno delle intestazioni.

Non ho mai scritto una funzione inline con una class di archiviazione diversa da quella static .

Dalla mia esperienza con GCC so che l’ static inline static e static inline differisce in un modo in cui il compilatore emette avvisi sulle funzioni inutilizzate. Più precisamente quando si dichiara static funzione static e non viene utilizzata nell’unità di traduzione corrente, il compilatore produce un avvertimento sulla funzione non utilizzata, ma è ansible inibire tale avviso modificandolo in static inline .

Quindi tendo a pensare che la static debba essere usata nelle unità di traduzione e trarre vantaggio dal compilatore di controlli extra per trovare le funzioni inutilizzate. E l’ static inline dovrebbe essere utilizzato nei file di intestazione per fornire funzioni che possono essere allineate (a causa dell’assenza di collegamento esterno) senza emettere avvisi.

Sfortunatamente non riesco a trovare alcuna prova per quella logica. Anche dalla documentazione GCC non sono stato in grado di concludere che l’ inline inibisca gli avvertimenti di funzione inutilizzati. Sarei grato se qualcuno condividesse i link con la descrizione di questo.

Una differenza che non è a livello di lingua ma il livello di implementazione più diffuso: alcune versioni di gcc rimuoveranno static inline funzioni static inline dall’output per impostazione predefinita, ma manterranno semplici funzioni static anche se non referenziate. Non sono sicuro di quali versioni si applichi, ma da un punto di vista pratico significa che potrebbe essere una buona idea usare sempre inline static funzioni static nelle intestazioni.

In C, static significa che la funzione o la variabile definite possono essere utilizzate solo in questo file (cioè l’unità compilata)

Quindi, static inline indica la funzione inline che può essere utilizzata solo in questo file.

MODIFICARE:

L’unità di compilazione dovrebbe essere L’unità di traduzione