Antworten:
inline
Weist den Compiler an, zu versuchen, den Funktionsinhalt in den aufrufenden Code einzubetten, anstatt einen tatsächlichen Aufruf auszuführen.
Für kleine Funktionen, die häufig aufgerufen werden und einen großen Leistungsunterschied bewirken können.
Dies ist jedoch nur ein "Hinweis", und der Compiler ignoriert ihn möglicherweise. Die meisten Compiler versuchen, "inline" zu arbeiten, auch wenn das Schlüsselwort im Rahmen der Optimierungen nicht verwendet wird, sofern dies möglich ist.
beispielsweise:
static int Inc(int i) {return i+1};
.... // some code
int i;
.... // some more code
for (i=0; i<999999; i = Inc(i)) {/*do something here*/};
Diese enge Schleife führt bei jeder Iteration einen Funktionsaufruf aus, und der Funktionsinhalt ist tatsächlich erheblich geringer als der Code, den der Compiler zum Ausführen des Aufrufs eingeben muss. inline
wird den Compiler im Wesentlichen anweisen, den obigen Code in ein Äquivalent von zu konvertieren:
int i;
....
for (i=0; i<999999; i = i+1) { /* do something here */};
Überspringen des eigentlichen Funktionsaufrufs und Zurückkehren
Offensichtlich ist dies ein Beispiel, um den Punkt zu zeigen, kein wirklicher Code.
static
bezieht sich auf den Umfang. In C bedeutet dies, dass die Funktion / Variable nur innerhalb derselben Übersetzungseinheit verwendet werden kann.
static
(mit oder ohne inline
) perfekt im Header sein, sehe keinen Grund warum nicht. Vorlagen ist für C ++, diese Frage ist über C.
inline
ist es ein guter Stil, sie explizit zu markieren , imo
inline
nicht anweisen , die Compiler alle Versuche zu tun , bei inlining. Der Programmierer kann lediglich den Funktionskörper in mehrere Übersetzungseinheiten ohne ODR-Verletzung aufnehmen. Ein Nebeneffekt davon ist, dass es dem Compiler ermöglicht wird, dies tatsächlich zu tun , wenn er die Funktion inline würde .
Standardmäßig ist eine Inline-Definition nur in der aktuellen Übersetzungseinheit gültig.
Wenn die Speicherklasse ist extern
, hat der Bezeichner eine externe Verknüpfung und die Inline-Definition liefert auch die externe Definition.
Wenn die Speicherklasse ist static
, hat der Bezeichner eine interne Verknüpfung und die Inline-Definition ist in anderen Übersetzungseinheiten nicht sichtbar.
Wenn die Speicherklasse nicht angegeben ist, ist die Inline-Definition nur in der aktuellen Übersetzungseinheit sichtbar, der Bezeichner ist jedoch weiterhin extern verknüpft, und eine externe Definition muss in einer anderen Übersetzungseinheit bereitgestellt werden. Dem Compiler steht es frei, entweder die Inline- oder die externe Definition zu verwenden, wenn die Funktion innerhalb der aktuellen Übersetzungseinheit aufgerufen wird.
Da der Compiler frei ist, jede Funktion zu inline (und nicht inline), deren Definition in der aktuellen Übersetzungseinheit sichtbar ist (und dank der Optimierung der Verbindungszeit auch in verschiedenen Übersetzungseinheiten, obwohl der C-Standard dies nicht wirklich berücksichtigt dass) für die meisten praktischen Zwecke gibt es keinen Unterschied zwischen static
und static inline
Funktionsdefinitionen.
Der inline
Bezeichner (wie die register
Speicherklasse) ist nur ein Compiler-Hinweis, und der Compiler kann ihn vollständig ignorieren. Standardkonforme nicht optimierende Compiler müssen nur ihre Nebenwirkungen berücksichtigen, und optimierende Compiler führen diese Optimierungen mit oder ohne explizite Hinweise durch.
inline
und register
sind jedoch nicht nutzlos, da sie den Compiler anweisen, Fehler auszulösen, wenn der Programmierer Code schreibt, der die Optimierungen unmöglich macht: Eine externe inline
Definition kann nicht auf Bezeichner mit interner Verknüpfung verweisen (da diese in einer anderen Übersetzungseinheit nicht verfügbar wären). oder definieren Sie modifizierbare lokale Variablen mit statischer Speicherdauer (da diese den Status für alle Übersetzungseinheiten nicht gemeinsam nutzen), und Sie können keine Adressen von register
qualifizierten Variablen verwenden.
Persönlich verwende ich die Konvention, um static
Funktionsdefinitionen auch in Headern zu markieren inline
, da der Hauptgrund für das Einfügen von Funktionsdefinitionen in Header-Dateien darin besteht, sie inlinierbar zu machen.
Im Allgemeinen verwende ich neben Deklarationen in Headern nur static inline
Funktions- und static const
Objektdefinitionen extern
.
Ich habe noch nie eine inline
Funktion mit einer anderen Speicherklasse als geschrieben static
.
inline
als ob sie tatsächlich auf Inlining zutrifft, ist irreführend und wohl falsch. Kein moderner Compiler verwendet es als Hinweis für Inline oder benötigt es, um das Inlining einer Funktion zu ermöglichen.
Aus meiner Erfahrung mit GCC weiß ich das static
und static inline
unterscheidet mich darin, wie der Compiler Warnungen vor nicht verwendeten Funktionen ausgibt. Genauer gesagt, wenn Sie deklarierenstatic
Funktion und sie in der aktuellen Übersetzungseinheit nicht verwendet wird, erzeugt der Compiler eine Warnung über nicht verwendete Funktionen. Sie können diese Warnung jedoch verhindern, indem Sie sie in ändern static inline
.
Daher neige ich dazu, das zu denken static
dies in Übersetzungseinheiten verwendet werden sollte und von zusätzlichen Überprüfungs-Compiler-Funktionen profitiert, um nicht verwendete Funktionen zu finden. Und static inline
sollte in Header-Dateien verwendet werden, um Funktionen bereitzustellen, die (aufgrund fehlender externer Verknüpfungen) ohne Warnungen integriert werden können.
Leider kann ich keine Beweise für diese Logik finden. Selbst aus der GCC-Dokumentation konnte ich nicht schließen, dass inline
nicht verwendete Funktionswarnungen verhindert werden. Ich würde mich freuen, wenn jemand Links zur Beschreibung davon teilt.
warning: unused function 'function' [clang-diagnostic-unused-function]
eine static inline
Funktion beim clang-tidy
Erstellen mit (v8.0.1), die in einer anderen Übersetzungseinheit verwendet wird. Aber definitiv ist dies eine der besten Erklärungen und Gründe für die Kombination von static
& inline
!
In C static
bedeutet , dass die von Ihnen definierte Funktion oder Variable nur in dieser Datei verwendet werden kann (dh in der Kompilierungseinheit).
Bedeutet static inline
also die Inline-Funktion, die nur in dieser Datei verwendet werden kann.
BEARBEITEN:
Die Kompilierungseinheit sollte die Übersetzungseinheit sein
the compile unit
ist etwas , was ich irrtümlich geschrieben habe, es gibt so etwas nicht, die eigentliche Terminologie isttranslation unit
Ein Unterschied, der nicht auf der Sprachebene, sondern auf der beliebten Implementierungsebene liegt: Bestimmte Versionen von gcc entfernen standardmäßig nicht referenzierte static inline
Funktionen aus der Ausgabe, behalten jedoch einfache static
Funktionen bei, auch wenn sie nicht referenziert sind. Ich bin nicht sicher, für welche Versionen dies gilt, aber aus praktischer Sicht bedeutet dies, dass es eine gute Idee sein kann, immer inline
für static
Funktionen in Headern zu verwenden.
inline
in der Definition? Bedeuten Sie auch, dass Sie es nicht für extern
Funktionen verwenden?
attribute((used))
und seine Verwendung ansehen, damit asm auf ansonsten nicht referenzierte static
Funktionen und Daten verweisen kann.
static
bezieht sich auf den Umfang. In C bedeutet dies, dass die Funktion / Variable nur innerhalb derselben Übersetzungseinheit verwendet werden kann.