6.7.4 Funktionsbezeichner
Eine neue Funktion von C99: Das inline
Schlüsselwort, adaptiert von C++, ist a Funktionsbezeichner die nur in Funktionsdeklarationen verwendet werden kann. Es ist nützlich für Programmoptimierungen, die erfordern, dass die Definition einer Funktion an der Stelle eines Aufrufs sichtbar ist. (Beachten Sie, dass der Standard nicht versucht, die Art dieser Optimierungen anzugeben.)
Die Sichtbarkeit ist gewährleistet, wenn die Funktion eine interne Verknüpfung hat oder wenn sie eine externe Verknüpfung hat und der Aufruf in derselben Übersetzungseinheit wie die externe Definition ist. In diesen Fällen ist das Vorhandensein der
inline
Das Schlüsselwort in einer Deklaration oder Definition der Funktion hat keine Auswirkung, außer darauf hinzuweisen, dass Aufrufe dieser Funktion gegenüber Aufrufen anderer Funktionen, die ohne deklariert wurden, bevorzugt optimiert werden sollten inline
Stichwort.
Sichtbarkeit ist ein Problem für einen Aufruf einer Funktion mit externer Verknüpfung, wo der Aufruf in einer anderen Übersetzungseinheit als der Definition der Funktion erfolgt. In diesem Fall ist die inline
Das Schlüsselwort ermöglicht, dass die Übersetzungseinheit, die den Aufruf enthält, auch eine lokale oder Inline-Definition der Funktion enthält.
Ein Programm kann eine Übersetzungseinheit mit einer externen Definition, eine Übersetzungseinheit mit einer Inline-Definition und eine Übersetzungseinheit mit einer Deklaration, aber keiner Definition für eine Funktion enthalten. Aufrufe in der letztgenannten Übersetzungseinheit verwenden wie üblich die externe Definition.
Eine Inline-Definition einer Funktion wird als eine andere Definition betrachtet als die externe Definition. Wenn ein Aufruf an eine Funktion func
bei externer Verknüpfung auftritt, wo eine Inline-Definition sichtbar ist, ist das Verhalten dasselbe, als ob der Aufruf beispielsweise an eine andere Funktion erfolgen würde
__func
, mit interner Verlinkung. Ein konformes Programm darf nicht davon abhängen, welche Funktion aufgerufen wird. Dies ist das Inline-Modell im Standard.
Ein konformes Programm darf sich weder auf die Implementierung unter Verwendung der Inline-Definition noch auf die Implementierung unter Verwendung der externen Definition verlassen. Die Adresse einer Funktion ist immer die Adresse, die der externen Definition entspricht, aber wenn diese Adresse zum Aufrufen der Funktion verwendet wird, könnte die Inline-Definition verwendet werden. Daher verhält sich das folgende Beispiel möglicherweise nicht wie erwartet.
inline const char *saddr(void)
{
static const char name[] = "saddr";
return name;
}
int compare_name(void)
{
return saddr() == saddr(); // unspecified behavior
}
Da die Implementierung möglicherweise die Inline-Definition für einen der Aufrufe von verwendet saddr
und die externe Definition für die andere verwenden, wird die Gleichheitsoperation nicht garantiert als 1 (wahr) ausgewertet. Dies zeigt, dass innerhalb der Inline-Definition definierte statische Objekte sich von ihrem entsprechenden Objekt in der externen Definition unterscheiden. Dies begründete den Zwang, sogar eine Nicht-Definition zu definieren.const
Objekt dieser Art.
Inlining wurde dem Standard so hinzugefügt, dass es mit vorhandener Linker-Technologie implementiert werden kann, und eine Teilmenge von C99-Inlining ist mit C++ kompatibel. Dies wurde dadurch erreicht, dass genau eine Übersetzungseinheit, die die Definition einer Inline-Funktion enthält, als diejenige angegeben werden muss, die die externe Definition für die Funktion bereitstellt. Weil diese Spezifikation einfach aus einer Deklaration besteht, der entweder die fehlt inline
Schlüsselwort oder enthält beides inline
und extern
wird es auch von einem C++-Übersetzer akzeptiert.
Inlining in C99 erweitert die C++-Spezifikation auf zwei Arten. Erstens, wenn eine Funktion deklariert ist
inline
in einer Übersetzungseinheit muss sie nicht deklariert werden inline
in jeder anderen Übersetzungseinheit. Dies ermöglicht beispielsweise eine Bibliotheksfunktion, die innerhalb der Bibliothek eingebunden werden soll, aber an anderer Stelle nur über eine externe Definition verfügbar ist. Die Alternative, eine Wrapper-Funktion für die externe Funktion zu verwenden, erfordert einen zusätzlichen Namen; und es kann sich auch nachteilig auf die Leistung auswirken, wenn ein Übersetzer nicht tatsächlich eine Inline-Ersetzung vornimmt.
Zweitens wird die Anforderung, dass alle Definitionen einer Inline-Funktion „genau gleich“ sein müssen, durch die Anforderung ersetzt, dass das Verhalten des Programms nicht davon abhängen sollte, ob ein Aufruf mit einer sichtbaren Inline-Definition oder der externen Definition von a implementiert wird Funktion. Dadurch kann eine Inline-Definition für ihre Verwendung innerhalb einer bestimmten Übersetzungseinheit spezialisiert werden. Beispielsweise kann die externe Definition einer Bibliotheksfunktion einige Argumentvalidierungen enthalten, die für Aufrufe von anderen Funktionen in derselben Bibliothek nicht erforderlich sind. Diese Erweiterungen bieten einige Vorteile; und Programmierer, die sich Sorgen um die Kompatibilität machen, können sich einfach an die strengeren C++-Regeln halten.
Beachten Sie, dass dies der Fall ist nicht geeignet für Implementierungen, um Inline-Definitionen von Standardbibliotheksfunktionen in den Standardheadern bereitzustellen, da dies einigen Legacy-Code beschädigen kann, der Standardbibliotheksfunktionen nach dem Einfügen ihrer Header neu deklariert. Das inline
Das Schlüsselwort soll Benutzern nur eine portable Möglichkeit bieten, das Inlining von Funktionen vorzuschlagen. Da die Standard-Header nicht portierbar sein müssen, haben Implementierungen andere Optionen wie:
#define abs(x) __builtin_abs(x)
oder andere nicht-portable Mechanismen zum Einbetten von Standardbibliotheksfunktionen.
grenzwertiges Duplikat von stackoverflow.com/questions/5369888/…
– Earlz
10. Juni 2011 um 22:40 Uhr
Und auch stackoverflow.com/questions/216510/extern-inline
– Nemo
10. Juni 2011 um 22:46 Uhr
@Earlz: Danke für den Link. Meine Frage bezieht sich auf die Begründung des zitierten Absatzes der Norm und ob es jemals Anwendungsfälle dafür gibt
inline
ohnestatic
undextern
, obwohl. Leider wird keines dieser Probleme in dieser Frage behandelt.– Sven Marnach
10. Juni 2011 um 22:46 Uhr
@Nemo: Ich habe diese Frage und die Antworten gelesen, bevor ich meine gepostet habe. Auch hier frage ich nicht “wie verhält es sich?” sondern “was ist die idee hinter diesem verhalten”? Ich bin mir ziemlich sicher, dass ich hier etwas übersehe.
– Sven Marnach
10. Juni 2011 um 22:49 Uhr
ja, deshalb sagte ich “grenzwertig”. Ich persönlich denke, das stellt eine ganz andere Frage
– Earlz
10. Juni 2011 um 22:57 Uhr