2010-03-06 9 views
5

Wenn ich in einem Header eine Nicht-Member-Funktion definiere, wird sie immer vom Compiler inline gesetzt, oder wählt der Compiler basierend auf seiner Heuristik? Ich weiß, dass __inline nur ein Hinweis ist, ist es das gleiche mit Funktionen in Headern?Sind in Header definierte Funktionen garantiert inline?

Antwort

11

Denken Sie daran, dass das Hinzufügen von etwas aus einem Header nicht anders ist, als nur direkt in der Quelldatei zu tippen. In einem Header zu sein, macht also keinen Unterschied, was den Compiler betrifft; es wusste nie, dass es da war.

Wenn Sie also eine Funktion in einer Header-Datei definieren und diese Header-Datei in eine Datei einfügen, ist es so, als ob Sie die Funktion direkt in die Datei eingegeben hätten. Nun stellt sich die Frage, "entscheidet sich der Compiler dafür, Dinge basierend auf Heuristiken einzubinden?"

Die Antwort ist "es hängt vom Compiler ab". Der Standard gibt keine Garantien darüber, was gefüttert wird oder nicht. Das heißt, jeder moderne Compiler wird extrem intelligent sein, was es inline, wahrscheinlich mit Heuristiken.

Allerdings kommen wir zu einem interessanten Punkt. Stellen Sie sich vor, Sie haben eine Funktion in einem Header und Sie fügen diesen Header in mehrere Quelldateien ein. Sie haben dann mehrere Definitionen der Funktion über Übersetzungseinheiten hinweg, und dies verstößt gegen die Definition für eine Definition. Ergo, Sie werden Kompilierungsfehler bekommen. (Der Linker-Fehler ist normalerweise etwas in der Art von: "Fehler, Funktion x bereits in y definiert") Sie können das Schlüsselwort inline verwenden, und Sie verletzen nicht mehr die ODR.

Übrigens __inline ist nicht Standard. Im Gegensatz zu Ihrem Post, ist es in der Regel eine Compiler-Erweiterung, die Kräfte Inlining, deutet es nicht. inline ist das Standardschlüsselwort, das ursprünglich auf Inlining hinweisen sollte. Wie du sagst, ignorieren die meisten modernen Compiler es in dieser Hinsicht vollständig und es ist nur der Zweck heutzutage, den Dingen interne Verbindungen zu geben.

+0

Irgendwelche Gedanken darüber, was heuristics ein moderner Compiler wie g ++ in seiner Entscheidung verwendet? d. h. ist es entlang der Linien von "inline jede Funktion, in der das Verhältnis von Call-Sites zu Bytes-in-Funktion-Körper weniger als X ist"? Oder ist es etwas subtiler? –

+0

@ Jeremy: Ich habe keine Ahnung, obwohl ich jetzt ziemlich interessiert bin, dass du es erwähnst. Ich werde heute Nacht nachsehen können. Ich vermute, dass es ziemlich kompliziert ist. – GManNickG

+1

@GMan: Das Bit über interne Verknüpfung ist falsch. 'inline' hat keinen Einfluss auf die Verknüpfung. In C++ hat eine Funktion, die als 'inline' deklariert ist, eine externe Verknüpfung (sofern nicht ausdrücklich als 'statisch' deklariert), genau wie jede andere Funktion auch. Das ODR für Inline-Funktionen ermöglicht speziell mehrere Definitionen in verschiedenen Übersetzungseinheiten, obwohl die Verknüpfung extern ist. – AnT

2

Es wird basierend auf Heuristiken wählen. Stellen Sie sicher, dass Sie es explizit als Inline deklarieren, andernfalls erhalten Sie möglicherweise einen doppelten Symbolverbindungsfehler, wenn Sie den Header in mehr als eine Kompilierungseinheit einschließen.

4

Vom C++ FAQ Lite:

Egal, wie Sie eine Funktion als Inline bezeichnen, es ist eine Anforderung, dass die Compiler ignorieren darf: es könnten einige Inline-expand, alle oder keine der Aufrufe einer Inline-Funktion.

2

Wenn Sie eine Funktion mit externer Bindung in einer Header-Datei definieren und füge ihn in mehr als eine Übersetzungseinheit, werden Sie Kompilierungsfehler erhalten (genauer: Linker erorr) für die Verletzung von One Definition Rule (ODR). Die Antwort ist also "Nein": Das Definieren einer Funktion in einer Header-Datei wird vom Compiler nicht als Hinweis auf Inlining verstanden und entbindet Sie nicht von der Einhaltung der ODR-Anforderungen. Nicht nur solche Funktionen sind nicht garantiert inline, aber höchstwahrscheinlich wird Ihr Programm nicht einmal kompilieren.

Um eine Funktion in einer Header-Datei zu definieren und damit durchzukommen, müssen Sie entweder eine interne Verknüpfung (deklarieren Sie es static, und am Ende mit separaten Funktion in jeder Übersetzungseinheit), oder erklären Sie es explizit inline.

Wie für die Heuristiken ...Moderne Compiler berücksichtigen normalerweise praktisch jede Funktion für Inlining (durch Anwendung von Heuristiken), unabhängig davon, wo sie definiert ist und ob sie explizit als inline deklariert ist oder nicht.

1

Es gibt keine Magie über Funktionen in Headern. Der Compiler weiß nicht einmal, ob eine Funktion in einem Header definiert ist oder nicht. (Da Header im Grunde nur in die Quelldatei kopiert/eingefügt werden, könnten Sie sie in einer Kopfzeile definieren, aber der Compiler sieht sie nur als Teil der Übersetzungseinheit)

Es gibt auch zwei verschiedene Bedeutungen von "Inline" beachten:

eine Funktion durch den C++ Standard definiert inlined sein kann: Dies geschieht entweder durch die Funktion mit dem inline Schlüsselwort Vorfixierung, oder wenn es eine Elementfunktion, indem es an Ort und Stelle im Innern der definierende Klassendefinition.

Die Folge davon ist, zu

  • die Linker mitteilen, dass sie die Funktionsdefinition in mehreren Dateien auftreten können, und es sollte sich nur zusammen leise verschmelzen, anstatt einen Fehler zu werfen
  • erleichtern der Compiler zum Ausführen der Inlining Optimierung.

Die inlining Optimierung auf der anderen Seite, ist einfach die Handlung eines Funktionsaufrufs durch den Körper der aufgerufenen Funktion zu ersetzen, was bedeutet, dass diese Optimierung tatsächlich Seiten aufrufen angewandt wird, nicht auf Funktionen. Eine Funktion könnte normalerweise an einigen Stellen aufgerufen werden, aber anderswo anders beschrieben. Ein Funktionsaufruf ist inline, wenn der Compiler sich so anfühlt, und es ist am besten, ihn vollständig von der ersten Bedeutung von "Inline" zu trennen.

Der Compiler wird die Inline-Optimierung anwenden, wenn, wann und wo es sich anfühlt. Es verwendet eine Menge Heuristiken dafür. Kleinere Funktionen sind eher inline. Wenn festgestellt wird, dass eine bestimmte Call-Site häufig genug ausgeführt wird, ist es wahrscheinlicher, dass sie inline ist. Letztendlich basieren die verwendeten Heuristiken auf "wird es die Leistung verbessern oder verschlechtern". Und es ist im Allgemeinen ein besserer Richter darüber als Menschen, also sollten Sie nicht wirklich wissen müssen, welche präzisen Heuristiken es verwendet. Zu viel Inlining schadet nur der Performance.

Verwandte Themen