C ++ Inline jest zupełnie inny niż 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
sam wpływa na kompilator, asembler i linker. Jest to dyrektywa dla kompilatora, która mówi, że emituje tylko symbol tej funkcji / danych, jeśli jest on używany w jednostce tłumaczącej, a jeśli tak, to podobnie jak metody klasowe, każ asemblerowi, aby zapisał je w sekcji .section .text.c::function(),"axG",@progbits,c::function(),comdat
lub .section .bss.i,"awG",@nobits,i,comdat
danych.
To następuje .section name, "flags"MG, @type, entsize, GroupName[, linkage]
. Na przykład nazwa sekcji jest i nie jest używana, jest teraz widoczna dla asemblera, aw rezultacie linkera, ponieważ nie jest przechowywany w regularnym.text.c::function()
. axG
oznacza, że sekcja jest alokowalna, wykonywalna i w grupie, tj. zostanie podana nazwa grupy (i nie ma flagi M, więc nie zostanie podany żaden rozmiar); lub etc przez montera z powodu ich dyrektyw.@progbits
oznacza, że sekcja zawiera dane i nie jest pusta; c::function()
to nazwa grupy i grupa macomdat
powiązanie oznacza, że we wszystkich plikach obiektowych wszystkie sekcje napotkane z tą nazwą grupy oznaczone tagiem comdat zostaną usunięte z ostatecznego pliku wykonywalnego, z wyjątkiem 1, tzn. kompilator upewnia się, że w jednostce tłumaczącej jest tylko jedna definicja, a następnie mówi asemblerowi, aby wstawił we własnej grupie w pliku obiektowym (1 sekcja w 1 grupie), a następnie linker upewni się, że jeśli jakiś plik obiektowy ma grupę o tej samej nazwie, to umieści tylko jeden w końcowym .exe. Różnica pomiędzyinline
inline
.data
.text
static inline
w klasie oznacza, że jest to definicja typu, a nie deklaracja (pozwala zdefiniować element statyczny w klasie) i uczynić ją wbudowaną; teraz działa jak wyżej.
static inline
w zakresie plików wpływa tylko na kompilator. Oznacza to, że dla kompilatora: emituje symbol tej funkcji / danych tylko wtedy, gdy jest używany w jednostce tłumaczącej i robi to jako zwykły symbol statyczny (przechowuj tekst. / Tekst bez dyrektywy .globl). Dla asemblera nie ma teraz różnicy między static
istatic inline
extern inline
to deklaracja, która oznacza, że musisz zdefiniować ten symbol w jednostce tłumaczeniowej lub wyrzucić błąd kompilatora; jeśli jest zdefiniowany, traktuj go jako zwykły, inline
a dla asemblera i linkera nie będzie różnicy między extern inline
i inline
, więc jest to tylko ochrona kompilatora.
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
Wszystko powyższe bez wiersza błędu zwija się do inline int i[5]
. Oczywiście, jeśli tak, extern inline int i[] = {5};
to extern
zostaniesz zignorowany z powodu wyraźnej definicji poprzez przypisanie.
inline
w przestrzeni nazw zobacz to i to