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;
}
inline
da 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(),comdat
o .section .bss.i,"awG",@nobits,i,comdat
per 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()
. axG
significa 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); @progbits
indica che la sezione contiene dati e non è vuota; c::function()
è il nome del gruppo e il gruppo hacomdat
collegamento 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 inline
e non utilizzo inline
è ora visibile all'assemblatore e di conseguenza al linker, perché non è memorizzato nel normale .data
o .text
ecc dall'assemblatore a causa delle loro direttive.
static inline
in 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 inline
nell'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 static
estatic 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 inline
e per l'assemblatore e il linker non ci sarà alcuna differenza tra extern inline
e 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 extern
sarebbe ignorato a causa della definizione esplicita attraverso l'assegnazione.
inline
su uno spazio dei nomi, vedi questo e questo