C ++ inline è totalmente diverso da C inline .
#include <iostream>
extern inline int i[];
int i [5];
struct c {
int function (){return 1;} //implicitly inline
static inline int j = 3; //explicitly inline
};
int main() {
c j;
std::cout << i;
}
inlineda solo influenza il compilatore, l'assemblatore e il linker. È una direttiva per il compilatore che dice di emettere un simbolo per questa funzione / dati solo se utilizzato nell'unità di traduzione, e se lo è, quindi come i metodi di classe, dire all'assemblatore di memorizzarli nella sezione .section .text.c::function(),"axG",@progbits,c::function(),comdato .section .bss.i,"awG",@nobits,i,comdatper i dati. Le istanze dei modelli vanno anche nei loro gruppi di comdat.
Questo segue .section name, "flags"MG, @type, entsize, GroupName[, linkage]. Ad esempio, il nome della sezione è .text.c::function(). axGsignifica che la sezione è allocabile, eseguibile e in un gruppo, cioè verrà specificato un nome di gruppo (e non c'è un flag M quindi non verrà specificato alcun entsize); @progbitsindica che la sezione contiene dati e non è vuota; c::function()è il nome del gruppo e il gruppo hacomdatcollegamento che significa che in tutti i file oggetto, tutte le sezioni incontrate con questo nome di gruppo taggato con comdat verranno rimosse dall'eseguibile finale ad eccezione di 1 ovvero il compilatore si assicura che ci sia una sola definizione nell'unità di traduzione e quindi dice all'assemblatore di mettere nel suo gruppo nel file oggetto (1 sezione in 1 gruppo) e quindi il linker farà in modo che se qualsiasi file oggetto ha un gruppo con lo stesso nome, includerne solo uno nel file .exe finale. La differenza tra inlinee non utilizzo inlineè ora visibile all'assemblatore e di conseguenza al linker, perché non è memorizzato nel normale .datao .textecc dall'assemblatore a causa delle loro direttive.
static inlinein una classe significa che si tratta di una definizione di tipo e non di una dichiarazione (consente di definire un membro statico nella classe) e di renderlo in linea; ora si comporta come sopra.
static inlinenell'ambito del file riguarda solo il compilatore. Significa per il compilatore: emettere un simbolo per questa funzione / dati solo se viene utilizzato nell'unità di traduzione e farlo come un normale simbolo statico (memorizzare in.text /.data senza la direttiva .globl). Per l'assemblatore non esiste ora alcuna differenza tra staticestatic inline
extern inlineè una dichiarazione che significa che è necessario definire questo simbolo nell'unità di traduzione o generare un errore del compilatore; se è definito, trattalo come un normale inlinee per l'assemblatore e il linker non ci sarà alcuna differenza tra extern inlinee inline, quindi questa è solo una protezione del compilatore.
extern inline int i[];
extern int i[]; //allowed repetition of declaration with incomplete type, inherits inline property
extern int i[5]; //declaration now has complete type
extern int i[5]; //allowed redeclaration if it is the same complete type or has not yet been completed
extern int i[6]; //error, redeclaration with different complete type
int i[5]; //definition, must have complete type and same complete type as the declaration if there is a declaration with a complete type
Tutto quanto sopra senza la riga di errore collassa a inline int i[5]. Ovviamente se avete fatto extern inline int i[] = {5};allora externsarebbe ignorato a causa della definizione esplicita attraverso l'assegnazione.
inlinesu uno spazio dei nomi, vedi questo e questo