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;
}
inlineallein 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(),comdatoder .section .bss.i,"awG",@nobits,i,comdatfür Daten zu speichern .
Dies folgt .section name, "flags"MG, @type, entsize, GroupName[, linkage]. Der Abschnittsname lautet beispielsweise .text.c::function(). axGbedeutet, 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); @progbitsbedeutet, 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 hatcomdatinlineund nicht verwenden inlineist jetzt für den Assembler und als Ergebnis für den Linker sichtbar, da es nicht im regulären .dataoder gespeichert ist.text vom Assembler aufgrund ihrer Anweisungen usw. .
static inlinein 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 inlineat 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 staticundstatic inline
extern inlineist 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 inlineund 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.
inlineSehen Sie dies und das in einem Namespace