1. Gründe für die Einführung des inline-Schlüsselworts
In C/C++ wurde, um das Problem zu lösen, dass einige häufig aufgerufene kleine Funktionen viel Stack-Speicher (Stack-Speicher) verbrauchen, speziell derinlineModifizierer eingeführt, der Inline-Funktionen kennzeichnet.
Stack-Speicher bezieht sich auf den Speicherplatz, der die lokalen Daten des Programms enthält (d. h. Daten innerhalb von Funktionen).
Unter dem System ist der Stack-Speicher begrenzt. Wenn er häufig und in großen Mengen verwendet wird, kann dies zu Programmfehlern aufgrund unzureichenden Stack-Speichers führen. Zum Beispiel ist das Endergebnis der unendlichen rekursiven Aufrufe einer Funktion die Erschöpfung des Stack-Speicherplatzes.
Sehen wir uns ein Beispiel an:
Beispiel
Das obige Beispiel ist die standardmäßige Verwendung von inline-Funktionen. DieinlineVorteile, die der Modifizierer mit sich bringt, sind nicht an der Oberfläche sichtbar. Tatsächlich wird intern bei jedemfor-Aufruf innerhalb der Schleifedbtest(i)wird ersetzt durch(i%2>0)?"odd":"even", wodurch der Verbrauch vermieden wird, der durch wiederholtes Reservieren von Stack-Speicher für häufige Funktionsaufrufe entsteht.
2. Einschränkungen der Verwendung von inline
inlineDie Verwendung ist etwas eingeschränkt. inline eignet sich nur für Funktionen mit einfachem Code im Funktionskörper. Es kann keine komplexen strukturellen Kontrollanweisungen wie while oder switch enthalten, und die inline-Funktion selbst kann keine direkt rekursive Funktion sein (d. h. eine Funktion, die sich intern selbst aufruft).
3. inline ist nur ein Vorschlag an den Compiler
inlineDie inline-Funktion ist nur ein Vorschlag an den Compiler, ob sie also letztendlich tatsächlich inline gesetzt werden kann, hängt vom Compiler ab. Wenn er der Meinung ist, dass die Funktion nicht komplex ist und an der Aufrufstelle erweitert werden kann, wird er sie wirklich inline setzen. Es ist nicht so, dass eine Deklaration als inline sie auch inline macht; die Deklaration als inline ist nur ein Vorschlag.
4. Es wird empfohlen, inline-Funktionsdefinitionen in Header-Dateien abzulegen
Zweitens, weil Inline-Funktionen an der Aufrufstelle expandiert werden müssen, muss derCompiler die Definition der Inline-Funktion überall sehen können. Andernfalls wird daraus ein Aufruf einer Nicht-Inline-Funktion. Daher erfordert dies, dass jede Datei, die die Inline-Funktion aufruft, dieDefinition der Inline-Funktion。
. Daher ist es sinnvoll, dieDefinition der Inline-Funktionin dieHeader-Dateizu setzen, wodurch Sie sich die Mühe ersparen, sie für jede Datei einmal zu implementieren.
Die Deklaration und die Definition müssen konsistent sein: Wenn die Inline-Funktion in jeder Datei einmal implementiert wird, sollte man am besten sicherstellen, dass jede Definition gleich ist; andernfalls führt dies zu undefiniertem Verhalten. Wenn die Definitionen in jeder Datei nicht gleich sind, hängt es vom jeweiligen Compiler ab, welche der Compiler expandiert. Daher ist es am besten, dieInline-Funktionsdefinitionin dieHeader-Datei.
5. Memberfunktionen in Klassen und inline
Definiertin einer Klassesind Memberfunktionenstandardmäßiginline. Wenn die Funktionsdefinition beim Definieren der Klasse innerhalb der Klasse angegeben wird, ist das natürlich am besten. Wenn die Memberfunktionsdefinition nicht in der Klasse angegeben wird, Sie aber die Funktion inline setzen möchten, müssen Sieinlinehinzufügen, andernfalls gilt es als nicht inline.
Obwohl es beim Schreiben praktisch ist, den Definitionskörper der Memberfunktion in die Klassendeklaration zu setzen, ist es kein guter Programmierstil. Das obige Beispiel sollte geändert werden zu:
6. inline ist ein "Schlüsselwort für die Implementierung"
Das Schlüsselwortinlinemuss zusammen mit dem Funktionsdefinitionskörper platziert werden, damit die Funktion inline wird. Allein das Setzen voninlinevor die Funktionsdeklaration hat keine Wirkung.
Eine Funktion des folgenden StilsFookann keine Inline-Funktion werden:
inline void Foo(int x, int y); // inline 仅与函数声明放在一起
void Foo(int x, int y){}
Hingegen wird eine Funktion des folgenden StilsFoozu einer Inline-Funktion:
void Foo(int x, int y);
inline void Foo(int x, int y) {} // inline 与函数定义体放在一起
Daher ist inline ein "Schlüsselwort für die Implementierung", kein "Schlüsselwort für die Deklaration." Im Allgemeinen können Benutzer die Funktionsdeklaration lesen, aber nicht die Funktionsdefinition sehen. Obwohl in den meisten Lehrbüchern das Schlüsselwort inline sowohl vor die Deklaration als auch vor den Definitionskörper von Inline-Funktionen gesetzt wird, denke ichinline sollte nicht in Funktionsdeklarationen erscheinen. Obwohl dieses Detail die Funktionalität der Funktion nicht beeinflusst, spiegelt es ein Grundprinzip eines hochwertigen C++/C-Programmierstils wider:Deklarationen und Definitionen sollten nicht verwechselt werden. Benutzer müssen nicht wissen und sollten nicht wissen, ob eine Funktion inline sein muss.
7. inline mit Vorsicht verwenden
Inline kann die Ausführungseffizienz von Funktionen verbessern. Warum nicht alle Funktionen als Inline-Funktionen definieren? Wenn alle Funktionen inline wären, wäre das Schlüsselwort "inline" dann noch notwendig?
Inline geht auf Kosten vonCodeaufblähung (Kopieren)und spart nur den Overhead von Funktionsaufrufen, wodurch die Ausführungseffizienz von Funktionen verbessert wird.
Wenn die Zeit zum Ausführen des Codes im Funktionskörper im Vergleich zum Overhead des Funktionsaufrufs groß ist, dann ist der Effizienzgewinn gering. Andererseits erfordert jeder Aufruf einer Inline-Funktion das Kopieren des Codes, was die Gesamtcodegröße des Programms erhöht und mehr Speicherplatz verbraucht.
Inline sollte in den folgenden Situationen nicht verwendet werden:
(1) Wenn der Code im Funktionskörperrelativ langist, führt die Verwendung von inline zuhöheren Speicherverbrauchskosten。
(2) Wenn es eineSchleifeim Funktionskörper gibt, dann ist die Zeit zum Ausführen des Codes im Funktionskörper größer als der Overhead des Funktionsaufrufs. Klassenkonstruktoren und -destruktoren können leicht dazu führen, dass Menschen fälschlicherweise denken, dass die Verwendung von inline effektiver ist. Achten Sie darauf, dassKonstruktoren und Destruktoren können einige Verhaltensweisen verbergen, wie z. B. das "heimliche" Ausführen derBasisklassen- oder MemberobjektKonstruktoren und -destruktoren. Deshalbsollten Sie die Definitionskörper von Konstruktoren und Destruktoren nicht einfach in die Klassendeklaration setzen. Ein guter Compiler wird nicht lohnenswertes inline anhand des Definitionskörpers der Funktion automatisch aufheben (dies zeigt außerdem, dass inline nicht in Funktionsdeklarationen erscheinen sollte).
8. Zusammenfassung
Inline-Funktionen sind kein Allheilmittel zur Leistungssteigerung. Nur wenndie Funktion sehr kurz ist, kann sie den gewünschten Effekt erzielen; wenn die Funktion jedoch nicht sehr kurz ist und an vielen Stellen aufgerufen wird, vergrößert sie die Größe der ausführbaren Datei.
Das Ärgerlichsteist, wennder Compiler sich weigert zu inlinen. In alten Implementierungen waren die Ergebnisse ziemlich unbefriedigend. Obwohl neue Implementierungen stark verbessert wurden, sind sie noch nicht perfekt. Einige Compiler sind clever genug, um anzugeben, welche Funktionen inline sein können und welche nicht, aber die meisten Compiler sind nicht so clever, daher erfordert dies unsere Erfahrung, um es zu beurteilen.Wenn Inline-Funktionen die Leistung nicht verbessern können, vermeiden Sie ihre Verwendung!
Original-Link: https://www.cnblogs.com/fnlingnzb-learner/p/6423917.html