C ++ Inline unterscheidet sich grundlegend von 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
allein wirkt sich auf den Compiler, Assembler und den Linker aus. Es ist eine Anweisung an den Compiler, dass nur dann ein Symbol für diese Funktion / Daten ausgegeben wird, wenn es in der Übersetzungseinheit verwendet wird, und wenn dies der Fall ist, weisen Sie den Assembler wie Klassenmethoden an, sie im Abschnitt .section .text.c::function(),"axG",@progbits,c::function(),comdat
oder .section .bss.i,"awG",@nobits,i,comdat
für Daten zu speichern .
Dies folgt .section name, "flags"MG, @type, entsize, GroupName[, linkage]
. Der Abschnittsname lautet beispielsweise .text.c::function()
. axG
bedeutet, dass der Abschnitt zuweisbar, ausführbar und in einer Gruppe ist, dh ein Gruppenname wird angegeben (und es gibt kein M-Flag, sodass keine Entsize angegeben wird); @progbits
bedeutet, dass der Abschnitt Daten enthält und nicht leer ist; Verknüpfung bedeutet, dass in allen Objektdateien alle Abschnitte mit diesem mit comdat gekennzeichneten Gruppennamen aus der endgültigen ausführbaren Datei entfernt werden, mit Ausnahme von 1, dh der Compiler stellt sicher, dass nur eine Definition in der Übersetzungseinheit vorhanden ist, und weist den Assembler an, diese zu setzen es in seiner eigenen Gruppe in der Objektdatei (1 Abschnitt in 1 Gruppe) und dann stellt der Linker sicher, dass, wenn Objektdateien eine Gruppe mit demselben Namen haben, nur eine in die endgültige EXE-Datei aufgenommen wird. Der Unterschied zwischenc::function()
ist der Gruppenname und die Gruppe hatcomdat
inline
und nicht verwenden inline
ist jetzt für den Assembler und als Ergebnis für den Linker sichtbar, da es nicht im regulären .data
oder gespeichert ist.text
vom Assembler aufgrund ihrer Anweisungen usw. .
static inline
in einer Klasse bedeutet dies, dass es sich um eine Typdefinition und nicht um eine Deklaration handelt (ermöglicht die Definition eines statischen Elements in der Klasse) und macht es inline; es verhält sich jetzt wie oben.
static inline
at file scope wirkt sich nur auf den Compiler aus. Für den Compiler bedeutet dies: Geben Sie nur dann ein Symbol für diese Funktion / Daten aus, wenn es in der Übersetzungseinheit verwendet wird, und zwar als reguläres statisches Symbol (speichern Sie in.text /.data ohne die Anweisung .globl). Für den Assembler gibt es jetzt keinen Unterschied zwischen static
undstatic inline
extern inline
ist eine Deklaration, die bedeutet, dass Sie dieses Symbol in der Übersetzungseinheit definieren oder einen Compilerfehler auslösen müssen. Wenn es definiert ist, behandeln Sie es als regulär inline
und für den Assembler und Linker gibt es keinen Unterschied zwischenextern inline
und inline
, daher ist dies nur ein Compiler-Schutz.
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
Das Ganze oben ohne die Fehlerzeile kollabiert zu inline int i[5]
. Natürlich, wenn du es extern inline int i[] = {5};
damals getan hastextern
würden die explizite Definition durch Zuordnung ignoriert fällig werden.
inline
Sehen Sie dies und das in einem Namespace