Ich verstehe, dass dies inline
für sich genommen ein Vorschlag für den Compiler ist und nach eigenem Ermessen die Funktion einbinden kann oder nicht, und dass er auch verknüpfbaren Objektcode erzeugt.
Ich denke, dass static inline
dies dasselbe tut (kann oder kann nicht inline sein), aber keinen verlinkbaren Objektcode erzeugt, wenn es inline ist (da kein anderes Modul darauf verlinken könnte).
Wo extern inline
passt das ins Bild?
Angenommen , ich eine Präprozessormakro durch eine Inline - Funktion ersetzt werden soll und verlangen , dass diese Funktion inlined wird ( zum Beispiel , weil es die verwendet __FILE__
und __LINE__
Makros , die für die Anrufer lösen sollen aber nicht so genannt Funktion). Das heißt, ich möchte einen Compiler- oder Linkerfehler sehen, falls die Funktion nicht inline wird. Tut extern inline
das? (Ich gehe davon aus, dass es keine andere Möglichkeit gibt, dieses Verhalten zu erreichen, als sich an ein Makro zu halten.)
Gibt es Unterschiede zwischen C ++ und C?
Gibt es Unterschiede zwischen verschiedenen Compiler-Anbietern und -Versionen?
quelle
extern inline
unterliegt sie der Ein-Definitions-Regel, und dies ist die Definition. Wenn jedoch die implementierungsdefinierten Optimierungsheuristiken der Empfehlung folgen, dasinline
Schlüsselwort als Vorschlag zu verwenden, dass "Aufrufe der Funktion so schnell wie möglich sein sollen" (ISO 9899: 1999 §6.7.4 (5),extern inline
zähltIch glaube, Sie verstehen __FILE__ und __LINE__ aufgrund dieser Aussage falsch:
Es gibt mehrere Phasen der Kompilierung, und die Vorverarbeitung ist die erste. __FILE__ und __LINE__ werden in dieser Phase ersetzt. Bis der Compiler die Funktion zum Inlining in Betracht ziehen kann, wurden sie bereits ersetzt.
quelle
Es hört sich so an, als würden Sie versuchen, so etwas zu schreiben:
und in der Hoffnung, dass jedes Mal andere Werte gedruckt werden. Wie Don sagt, werden Sie nicht, weil __FILE__ und __LINE__ vom Präprozessor implementiert werden, aber Inline vom Compiler implementiert wird. Wo immer Sie printLocation aufrufen, erhalten Sie das gleiche Ergebnis.
Die einzige Möglichkeit, dies zum Laufen zu bringen, besteht darin, printLocation zu einem Makro zu machen. (Ja, ich weiß...)
quelle
Die Situation mit Inline, statischem Inline und externem Inline ist kompliziert, nicht zuletzt, weil gcc und C99 leicht unterschiedliche Bedeutungen für ihr Verhalten definieren (und vermutlich auch C ++). Sie können einige nützliche und detaillierte Informationen finden , was sie in C tun hier .
quelle
Hier wählen Sie eher Makros als Inline-Funktionen. Eine seltene Gelegenheit, in der Makros über Inline-Funktionen herrschen. Versuchen Sie Folgendes: Ich habe diesen "MACRO MAGIC" -Code geschrieben und er sollte funktionieren! Getestet auf gcc / g ++ Ubuntu 10.04
Definieren Sie diese Makros für mehrere Dateien in einer separaten Header-Datei, einschließlich derselben in jeder c / cc / cxx / cpp-Datei. Bitte bevorzugen Sie nach Möglichkeit Inline-Funktionen oder konstante Bezeichner (je nach Fall) gegenüber Makros.
quelle
Anstatt zu antworten "Was macht es?", Antworte ich "Wie bringe ich es dazu, das zu tun, was ich will?" Es gibt 5 Arten von Inlining, die alle in GNU C89, Standard C99 und C ++ verfügbar sind:
immer inline, es sei denn, die Adresse ist vergeben
Fügen Sie
__attribute__((always_inline))
eine Erklärung hinzu und verwenden Sie dann einen der folgenden Fälle, um die Möglichkeit zu prüfen, dass die Adresse verwendet wird.Sie sollten dies wahrscheinlich niemals verwenden, es sei denn, Sie benötigen seine Semantik (z. B. um die Assembly auf eine bestimmte Weise zu beeinflussen oder um sie zu verwenden
alloca
). Der Compiler weiß normalerweise besser als Sie, ob es sich lohnt.Inline und ein schwaches Symbol ausgeben (wie C ++, auch bekannt als "Lass es einfach funktionieren")
Beachten Sie, dass dadurch eine Reihe von Kopien desselben Codes herumliegen und der Linker eine willkürlich auswählt.
Inline, aber niemals ein Symbol ausgeben (externe Referenzen hinterlassen)
immer ausgeben (für eine TU, um das vorhergehende aufzulösen)
Die angedeutete Version gibt ein schwaches Symbol in C ++ aus, aber ein starkes Symbol in beiden Dialekten von C:
Oder Sie können es ohne den Hinweis tun, der in beiden Sprachen ein starkes Symbol ausgibt:
Im Allgemeinen wissen Sie, welche Sprache Ihre TU ist, wenn Sie die Definitionen bereitstellen, und benötigen wahrscheinlich nicht viel Inlining.
Inline und emittieren in jeder TU
Für alle diese außer der
static
einen können Sievoid foo(void)
oben eine Erklärung hinzufügen . Dies hilft bei der "Best Practice", saubere Header zu schreiben und dann#include
eine separate Datei mit den Inline-Definitionen zu erstellen. Wenn Sie dann Inlines im C-Stil verwenden, unterscheiden sich#define
einige Makros in einer dedizierten TU, um die Out-of-Line-Definitionen bereitzustellen.Vergessen Sie nicht,
extern "C"
ob der Header sowohl von C als auch von C ++ verwendet werden kann!quelle
nm
Äquivalent ausführen soll .