Frage

Wenn wir eine Mitgliedsfunktion in der Klassendefinition selbst definieren, wird sie notwendigerweise inline behandelt oder ist sie nur eine Anfrage an den Compiler, den sie ignorieren kann.

War es hilfreich?

Lösung

Ja, Funktionen, die in einem Klassenkörper definiert sind inline.

(Wie bei anderen Funktionen erklärt inline Dies bedeutet nicht, dass das Komplier an Orten, an denen die Funktion aufgerufen wird Die Funktion wird verwendet.)

Andere Tipps

Wie von anderen angegeben, wird eine in einer Klasse definierte Methode automatisch inline angefordert. Es ist nützlich zu verstehen, warum.

Angenommen, es war nicht. Sie müssten Code für eine solche Funktion generieren, und überall, wo er aufgerufen wird, müsste ein Sprung zur Unterroutine -Anweisung über den Linker auf den Ort verweisen.

class A {
public:
  void f() { ... your code ... }
};

Jedes Mal, wenn dieser Code gesehen wird, kann der Compiler nur annehmen, dass er generiert werden muss, sodass er ein Symbol erzeugt. Angenommen, es war so:

A__f_v:

Wenn dieses Symbol global wäre, wenn Sie diesen Klassencode mehrmals in verschiedenen Modulen einbezogen haben, hätten Sie zum Verknüpfungszeit einen multiplizierten Symbolfehler. Es kann also nicht global sein. Stattdessen ist es ein lokales Datei.

Stellen Sie sich vor, Sie geben die obige Header -Datei in eine Reihe von Modulen ein. In jedem einzelnen wird es eine lokale Kopie dieses Codes generieren. Das ist besser als überhaupt nicht zu kompilieren, aber Sie erhalten mehrere Kopien des Codes, wenn Sie wirklich nur einen benötigen.

Dies führt zu der folgenden Schlussfolgerung: Wenn Ihr Compiler keine Funktion inline in die Einstellung, ist es Ihnen wesentlich besser, sie irgendwo zu deklarieren, und sie nicht beantragt, einzulegen.

Leider ist und nicht inline ist und ist nicht tragbar. Es wird vom Compiler -Schriftsteller definiert. Eine gute Faustregel ist es, immer jeden Liner, insbesondere alle Funktionen, die selbst eine Funktion, Inline, zu machen, wenn Sie Overhead entfernen. Alles unter drei Zeilen linearer Code ist mit ziemlicher Sicherheit in Ordnung. Wenn Sie jedoch eine Schleife im Code haben, stellt sich die Frage, ob der Compiler ihn inline zulässt, und mehr auf den Punkt, wie viel Nutzen Sie sehen würden, selbst wenn er das getan hat, was Sie wollen.

Betrachten Sie diesen Inline -Code:

inline int add(int a, int b) { return a + b; }

Es ist nicht nur fast so klein wie der Prototyp im Quellcode, sondern die durch den Inline -Code generierte Assemblersprache ist kleiner als der Aufruf an eine Routine. Dieser Code ist also kleiner und schneller.

Und wenn Sie zufällig in Konstanten vorbeikommen:

int c= add(5,4);

Es ist zur Kompilierung der Zeit aufgelöst und es gibt keinen Code.

In GCC habe ich kürzlich bemerkt, dass, selbst wenn ich keinen Code inliniert habe, wenn er in einer Datei lokal ist, sie ihn trotzdem schleichend einfügen. Nur wenn ich die Funktion in einem separaten Quellmodul erkläre, optimieren sie den Anruf nicht.

Nehmen wir am anderen Ende des Spektrums an, dass Sie Inline in einem 1000 -Zeilen -Code anfordern. Auch wenn Ihr Compiler albern genug ist, um mitzunehmen, ist das einzige, was Sie sparen , Ihr Code wächst um die Größe der Routine * n. Alles, was größer als 10 Zeilen ist, ist es so ziemlich, dass es sich nicht lohnt, einzubekommen, außer dem Sonderfall, in dem es nur eine sehr geringe Anzahl von Male bezeichnet wird. Ein Beispiel dafür könnte sich in einer privaten Methode befinden, die nur von 2 anderen bezeichnet wird.

Wenn Sie eine Methode mit einer Schleife inzieren, ist dies nur sinnvoll, wenn sie häufig eine kleine Anzahl von Male ausführt. Aber betrachten Sie eine Schleife, die eine Million Mal iteriert. Auch wenn der Code eingebaut ist, ist der Prozentsatz der Zeit, die im Anruf verbracht wird, winzig. Wenn Sie also Methoden mit Schleifen haben, die ohnehin größer sind, sind diese es wert Ich werde keinen Nutzen bieten

Es wird notwendigerweise vom Compiler als Antrag auf Inline behandelt - die es ignorieren kann. Es gibt einige Redewendungen, um einige Funktionen im Header (z. Gotw #33 für mehr Informationen.

Einige haben festgestellt, dass der Compiler möglicherweise sogar Funktionen inline, zu denen Sie ihn nie gefragt haben, aber ich bin mir nicht sicher, ob dies den Zweck der Bitten eines Inline -Inline -Inline -Inline -Unternehmens besiegen würde.

Es ist in der Tat eingebaut - aber jede Inline -Anfrage kann vom Compiler ignoriert werden.

Es ist eine Anfrage an den Compiler, den es ignorieren kann.

Der 2003 ISO C ++ Standard sagt

7.1.2/2 Eine Funktionserklärung (8.3.5, 9.3, 11.4) mit einem Inline -Spezifizierer deklariert eine Inline -Funktion. Der Inline -Spezifizierer zeigt die Implementierung an, dass die Inline -Substitution der Funktionskörper am Anlaufpunkt dem üblichen Funktionsaufruf vorgezogen werden soll
Mechanismus. Eine Implementierung ist nicht erforderlich, um diese Inline durchzuführen
Substitution am Anlaufpunkt; Allerdings auch, wenn diese Einstellung
Die Substitution wird weggelassen, die anderen durch 7.1.2 definierten Inline -Funktionen werden weiterhin respektiert.

7.1.2/3 Eine in einer Klassendefinition definierte Funktion ist eine Inline
Funktion. Der Inline -Spezifizierer darf nicht in einer Blockabläuf -Funktionserklärung angezeigt werden.

7.1.2/4 Eine Inline -Funktion muss in jeder Übersetzungseinheit in definiert werden
was es verwendet wird und in jeder genau die gleiche Definition haben soll
Fall (3.2). [Hinweis: Es kann ein Aufruf der Inline -Funktion auftreten
Bevor seine Defi-Nition in der Übersetzungseinheit erscheint. ] Wenn eine Funktion mit externer Verknüpfung in einer Übersetzungseinheit inline deklariert wird, wird sie in allen Übersetzungseinheiten, in denen sie erscheint, inline deklariert; Es ist keine Diagnose erforderlich. Eine Inline -Funktion mit externer Verknüpfung muss in allen Übersetzungseinheiten dieselbe Adresse haben. Eine statische lokale Variable in einer externen Inline
Funktion bezieht sich immer auf dasselbe Objekt. Ein String buchstäblich in einem
Die externe Inline -Funktion ist dasselbe Objekt in unterschiedlicher Übersetzung
Einheiten.

Es gibt zwei Dinge, die nicht zusammengefasst werden sollten:

  1. Wie Sie eine Funktion als Inline markieren: Definieren Sie sie mit Inline vor der Signatur oder definieren Sie sie an Deklarationspunkt;
  2. Was der Compiler mit einer solchen Inline -Markierung behandelt wird: Unabhängig davon, wie Sie die Funktion als Inline markiert haben, wird sie vom Compiler als Anfrage behandelt.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top