26 Stimmen

Inline-Schlüsselwort vs. Header-Definition

Was ist der Unterschied zwischen der Verwendung des Inline-Schlüsselworts vor einer Funktion und der bloßen Deklaration der gesamten Funktion im Header?

Also...

int whatever() { return 4; }

gegen

.h:

inline int whatever();

.cpp:

inline int myClass::whatever()
{
    return 4;
}

Und was bewirkt dies?

inline int whatever() { return 4; }

29voto

Matthieu M. Punkte 266317

Es gibt mehrere Facetten:

Sprache

  • Wenn eine Funktion mit dem Symbol inline Schlüsselwort, dann sollte seine Definition in der TU verfügbar sein, oder das Programm ist schlecht geformt.
  • Jede Funktion, die direkt in der Klassendefinition definiert wird, ist implizit gekennzeichnet inline .
  • Eine Funktion mit der Bezeichnung inline (implizit oder explizit) in mehreren TUs definiert werden können (unter Beachtung der ODR), während dies bei regulären Funktionen nicht der Fall ist.
  • Schablonenfunktionen (nicht vollständig spezialisiert) werden genauso behandelt wie inline ein.

Compiler-Verhalten

  • Eine Funktion mit der Bezeichnung inline wird als schwaches Symbol in jeder Objektdatei ausgegeben, wo es notwendig ist, was ihre Größe erhöhen kann (siehe Template Bloat).
  • Wo der Compiler den Aufruf tatsächlich einbindet (d. h. den Code an der Verwendungsstelle kopiert und einfügt, anstatt einen regulären Funktionsaufruf durchzuführen), liegt ganz im Ermessen des Compilers. Das Vorhandensein des Schlüsselworts kann die Entscheidung beeinflussen oder auch nicht, aber es ist bestenfalls eine Hinweis .

Linker-Verhalten

  • Schwache Symbole werden zusammengeführt, damit sie in der endgültigen Bibliothek nur noch einmal vorkommen. Ein guter Linker könnte prüfen, ob die verschiedenen Definitionen übereinstimmen, aber das ist nicht erforderlich.

10voto

justin Punkte 103032

ohne inline werden Sie wahrscheinlich mehrere exportierte Symbole erhalten, wenn die Funktion im Namespace oder im globalen Bereich deklariert ist (führt zu Linker-Fehlern).

Für eine Klasse (wie in Ihrem Beispiel) deklarieren die meisten Compiler die Methode jedoch implizit als Inline-Methode ( -fno-default-inline wird diese Vorgabe im GCC deaktivieren).

Wenn Sie eine Funktion als Inline deklarieren, kann es sein, dass der Compiler erwartet, ihre Definition in der Übersetzung zu sehen. Daher sollten Sie sie für die Zeiten reservieren, in denen die Definition sichtbar ist.

auf einer höheren Ebene: eine Definition in der Klassendeklaration ist häufig für mehrere Übersetzungen sichtbar. Dies kann zu einer besseren Optimierung und zu einer längeren Kompilierzeit führen.

es sei denn, manuelle Optimierung und schnelle Kompilierung sind wichtig, dann ist es heutzutage unüblich, das Schlüsselwort in einer Klassendeklaration zu verwenden.

10voto

Mike Seymour Punkte 242473

Der Zweck der inline ist, dass eine Funktion in mehr als einer Übersetzungseinheit definiert werden kann, was für einige Compiler notwendig ist, um die Funktion überall dort einbinden zu können, wo sie verwendet wird. Es sollte immer dann verwendet werden, wenn Sie eine Funktion in einer Header-Datei definieren, obwohl Sie es bei der Definition einer Vorlage oder einer Funktion innerhalb einer Klassendefinition weglassen können.

Definition in einer Kopfzeile ohne inline ist eine sehr schlechte Idee; wenn Sie den Header von mehr als einer Übersetzungseinheit einbinden, verletzen Sie die Eine-Definition-Regel; Ihr Code wird wahrscheinlich nicht verlinkt und kann ein undefiniertes Verhalten zeigen, wenn er es tut.

Die Deklaration in einer Kopfzeile mit inline Die Definition muss in jeder Übersetzungseinheit verfügbar sein, die sie verwendet, aber durch die Definition in einer Quelldatei ist sie nur in einer Übersetzungseinheit verfügbar. Wenn eine andere Quelldatei den Header enthält und versucht, die Funktion aufzurufen, dann ist Ihr Programm ungültig.

3voto

Cray Punkte 2266

Diese Frage erklärt eine Menge über Inline-Funktionen Was bedeutet __inline__? (auch wenn es sich um Inline Stichwort).

Im Grunde hat es nichts mit der Kopfzeile zu tun. Die Deklaration der gesamten Funktion in der Kopfzeile ändert nur die Quelldatei, in der sich der Quelltext der Funktion befindet. Das Inline-Schlüsselwort ändert, wo die resultierende kompilierte Funktion platziert werden - an einem eigenen Ort, so dass jeder Aufruf dorthin geht, oder anstelle eines jeden Aufrufs (besser für die Leistung). Allerdings wählen Compiler manchmal selbst aus, welche Funktionen oder Methoden sie inline schalten wollen, und Schlüsselwörter sind einfach Vorschläge für den Compiler. Auch Funktionen, die nicht als Inline-Funktionen spezifiziert wurden, können vom Compiler als Inline-Funktionen ausgewählt werden, wenn dies zu einer besseren Leistung führt.

1voto

Tony Delroy Punkte 98528

Wenn Sie mehrere Objekte in eine ausführbare Datei einbinden, sollte es normalerweise nur ein Objekt geben, das die Definition der Funktion enthält. Für int whatever() { return 4; } - Jede Übersetzungseinheit, die zur Erzeugung eines Objekts verwendet wird, enthält eine Definition (d. h. ausführbaren Code) für das whatever Funktion. Der Linker wird nicht wissen, zu welcher Funktion er den Aufrufer leiten soll. Wenn inline bereitgestellt wird, kann der ausführbare Code an den Aufrufstellen eingefügt werden oder auch nicht, aber wenn dies nicht der Fall ist, kann der Linker davon ausgehen, dass alle Definitionen gleich sind, und willkürlich eine auswählen, zu der der Aufrufer geleitet wird. Wenn die Definitionen nicht übereinstimmen, wird dies als IHR Fehler angesehen und Sie erhalten undefiniertes Verhalten. Zur Verwendung inline Ihre Idee, eine Inline-Deklaration in einen Header und die Inline-Definition in eine .cpp-Datei zu setzen, wird also nur funktionieren, wenn alle Aufrufer zufällig später in derselben .cpp-Datei sind - im Allgemeinen ist das nicht möglich, und Sie würden erwarten, dass die Definition der (nominell) Inline-Funktion in dem Header erscheint, der sie deklariert (oder dass es eine einzige Definition ohne vorherige Deklaration gibt).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X