Wann sollte ich das Schlüsselwort 'inline' für eine Funktion / Methode schreiben?

562

Wann sollte ich das Schlüsselwort inlinefür eine Funktion / Methode in C ++ schreiben ?

Nachdem Sie einige Antworten gesehen haben, einige verwandte Fragen:

  • Wann sollte ich das Schlüsselwort 'inline' für eine Funktion / Methode in C ++ nicht schreiben?

  • Wann weiß der Compiler nicht, wann eine Funktion / Methode 'inline' gemacht werden soll?

  • Ist es wichtig, ob eine Anwendung Multithreading ist, wenn man 'Inline' für eine Funktion / Methode schreibt?

Teilweise
quelle
40
Wenn Sie eine Funktion in einem Header definieren, müssen Sie sie inline deklarieren. Andernfalls erhalten Sie Linkerfehler zu mehreren Definitionen der Funktion.
Martin York
15
@ Martin: Es sei denn, es ist in einer Klassendefinition, wählerisch zu sein.
David Thornley
20
@ David: Um besonders wählerisch zu sein, liegt das nur daran, dass solche Funktionen implizit markiert sind inline(9.3 / 2).
Leichtigkeitsrennen im Orbit
Siehe auch Inline-Funktionen in den C ++ - FAQ. Sie haben eine sehr gute Behandlung von Inline.
JWW

Antworten:

882

Oh Mann, einer meiner Lieblingstiere.

inlineist mehr wie staticoder externals eine Richtlinie , den Compiler zu sagen Ihre Funktionen inline. extern, static, inlineSind Verknüpfung Richtlinien, fast ausschließlich durch den Linker verwendet wird , nicht der Compiler.

Es wird gesagt, dass inlineder Compiler darauf hinweist, dass Sie der Meinung sind, dass die Funktion inline sein sollte. Das mag 1998 wahr gewesen sein, aber ein Jahrzehnt später braucht der Compiler keine solchen Hinweise. Ganz zu schweigen davon, dass Menschen normalerweise falsch liegen, wenn es um die Optimierung von Code geht. Daher ignorieren die meisten Compiler den „Hinweis“.

  • static- Der Name der Variablen / Funktion kann nicht in anderen Übersetzungseinheiten verwendet werden. Linker muss sicherstellen, dass nicht versehentlich eine statisch definierte Variable / Funktion einer anderen Übersetzungseinheit verwendet wird.

  • extern- Verwenden Sie diesen Variablen- / Funktionsnamen in dieser Übersetzungseinheit, aber beschweren Sie sich nicht, wenn er nicht definiert ist. Der Linker sortiert es und stellt sicher, dass der gesamte Code, der versucht hat, ein externes Symbol zu verwenden, seine Adresse hat.

  • inline- Diese Funktion wird in mehreren Übersetzungseinheiten definiert. Machen Sie sich keine Sorgen. Der Linker muss sicherstellen, dass alle Übersetzungseinheiten eine einzelne Instanz der Variablen / Funktion verwenden.

Hinweis: Im Allgemeinen ist das Deklarieren von Vorlagen inlinesinnlos, da sie bereits die Verknüpfungssemantik von haben inline. Allerdings explizite Spezialisierung und Instanziierung von Templates benötigeninline verwendet werden.


Spezifische Antworten auf Ihre Fragen:

  • Wann sollte ich das Schlüsselwort 'inline' für eine Funktion / Methode in C ++ schreiben?

    Nur wenn Sie möchten, dass die Funktion in einem Header definiert wird. Genauer gesagt nur, wenn die Definition der Funktion in mehreren Übersetzungseinheiten angezeigt werden kann. Es ist eine gute Idee, kleine (wie in einem Liner) Funktionen in der Header-Datei zu definieren, da der Compiler mehr Informationen erhält, mit denen er arbeiten kann, während er Ihren Code optimiert. Es erhöht auch die Kompilierungszeit.

  • Wann sollte ich das Schlüsselwort 'inline' für eine Funktion / Methode in C ++ nicht schreiben?

    Fügen Sie keine Inline hinzu, nur weil Sie glauben, dass Ihr Code schneller ausgeführt wird, wenn der Compiler ihn inline macht.

  • Wann weiß der Compiler nicht, wann eine Funktion / Methode 'inline' gemacht werden soll?

    Im Allgemeinen kann der Compiler dies besser als Sie. Der Compiler hat jedoch nicht die Möglichkeit, Code zu integrieren, wenn er nicht über die Funktionsdefinition verfügt. In maximal optimiertem Code werden normalerweise alle privateMethoden eingefügt, unabhängig davon, ob Sie danach fragen oder nicht.

    Um Inlining in GCC zu verhindern, verwenden Sie __attribute__(( noinline ))und in Visual Studio __declspec(noinline).

  • Ist es wichtig, ob eine Anwendung Multithreading ist, wenn man 'Inline' für eine Funktion / Methode schreibt?

    Multithreading hat keinerlei Auswirkungen auf das Inlining.

deft_code
quelle
172
+1 Beste Beschreibung von Inline, die ich in ... gesehen habe (für immer). Ich werde Sie jetzt verarschen und dies in all meinen Erklärungen des Inline-Schlüsselworts verwenden.
Martin York
6
@ Ziggy, was ich sagen wollte war, dass Compiler-Inlining und das inlineSchlüsselwort nicht zusammenhängen. Du hast aber die richtige Idee. Das Erraten, was durch Inlining verbessert werden würde, ist in der Regel sehr fehleranfällig. Die Ausnahme von dieser Regel sind Einzeiler.
Deft_code
4
Diese Antwort verwirrt mich ein bisschen. Sie sagen das alles darüber, dass der Compiler in der Lage ist, Dinge besser zu inline / nicht inline zu machen. Dann sagen Sie, dass Sie einen Liner / kleine Funktionen in den Header einfügen sollten und dass der Compiler ohne die Funktionsdefinition keinen Inline-Code einfügen kann. Sind diese nicht ein bisschen widersprüchlich? Warum nicht einfach alles in die cpp-Datei einfügen und den Compiler entscheiden lassen?
user673679
5
Der Compiler führt nur Inline-Funktionsaufrufe durch, bei denen die Definition am Aufrufstandort verfügbar ist. Wenn Sie alle Funktionen in der CPP-Datei belassen, wird das Inlining auf diese Datei beschränkt. Ich schlage vor, kleine Einzeiler inline in .h zu definieren, da die Kosten für die Kompilierungsgeschwindigkeit vernachlässigbar sind und Sie fast garantiert sind, dass der Compiler den Aufruf inline macht. Mein Punkt beim Compiler-Inlining ist, dass es ein Port der schwarzen Kunst der Optimierung ist, bei der Ihr Compiler viel besser ist als Sie.
Deft_code
8
Immer wenn ich etwas über das kumulative Wissen des Internets lese, muss ich an John Lawtons berühmtes Zitat denken: Die Ironie des Informationszeitalters ist, dass es uninformierten Meinungen neuen Respekt verleiht.
Unsichtbarer
60

Ich möchte mit einem überzeugenden Beispiel zu all den großartigen Antworten in diesem Thread beitragen, um verbleibende Missverständnisse zu zerstreuen.

Gegeben zwei Quelldateien, wie:

  • inline111.cpp:

    #include <iostream>
    
    void bar();
    
    inline int fun() {
      return 111;
    }
    
    int main() {
      std::cout << "inline111: fun() = " << fun() << ", &fun = " << (void*) &fun;
      bar();
    }
  • inline222.cpp:

    #include <iostream>
    
    inline int fun() {
      return 222;
    }
    
    void bar() {
      std::cout << "inline222: fun() = " << fun() << ", &fun = " << (void*) &fun;
    }

  • Fall A:

    Kompilieren :

    g++ -std=c++11 inline111.cpp inline222.cpp

    Ausgabe :

    inline111: fun() = 111, &fun = 0x4029a0
    inline222: fun() = 111, &fun = 0x4029a0

    Diskussion :

    1. Selbst wenn Sie identische Definitionen Ihrer Inline-Funktionen haben sollten, kennzeichnet der C ++ - Compiler diese nicht, wenn dies nicht der Fall ist (aufgrund der separaten Kompilierung gibt es keine Möglichkeit, dies zu überprüfen). Es ist Ihre eigene Pflicht, dies sicherzustellen!

    2. Linker beschwert sich nicht über One Definition Rule , wie fun()als deklariert inline. Da inline111.cpp jedoch die erste fun()vom Compiler verarbeitete Übersetzungseinheit ist (die tatsächlich aufruft ), instanziiert der Compiler fun()bei seiner ersten Aufruf-Begegnung in inline111.cpp . Wenn Compiler entscheidet , nicht zu erweitern fun()von anderswo in Ihrem Programm auf seine Forderung ( zB von inline222.cpp ), der Aufruf an fun()wird immer wieder in seine Instanz von erzeugt verknüpft wird inline111.cpp (Aufruf von fun()innen inline222.cppkann auch eine Instanz in dieser Übersetzungseinheit erzeugen, bleibt jedoch nicht verbunden). Dies geht aus den identischen &fun = 0x4029a0Ausdrucken hervor.

    3. Schließlich trotz der inlineVorschlag an den Compiler zu tatsächlich erweitern die Einzeiler fun(), es ignoriert Ihren Vorschlag vollständig, was da klar ist , fun() = 111in beiden Leitungen.


  • Fall B:

    Kompilieren (umgekehrte Reihenfolge beachten) :

    g++ -std=c++11 inline222.cpp inline111.cpp

    Ausgabe :

    inline111: fun() = 222, &fun = 0x402980
    inline222: fun() = 222, &fun = 0x402980

    Diskussion :

    1. Dieser Fall bestätigt, was in Fall A besprochen wurde .

    2. Beachten Sie einen wichtigen Punkt: Wenn Sie den tatsächlichen Aufruf von fun()in inline222.cpp auskommentieren ( z. B. die Kommentarausgabe coutin inline222.cpp vollständig auskommentieren ), wird er trotz der Kompilierungsreihenfolge Ihrer Übersetzungseinheiten fun()beim ersten Aufruf in instanziiert inline111.cpp , was zum Ausdruck für Fall B als führt inline111: fun() = 111, &fun = 0x402980.


  • Fall C:

    Kompilieren (Hinweis -O2) :

    g++ -std=c++11 -O2 inline222.cpp inline111.cpp

    oder

    g++ -std=c++11 -O2 inline111.cpp inline222.cpp

    Ausgabe :

    inline111: fun() = 111, &fun = 0x402900
    inline222: fun() = 222, &fun = 0x402900

    Diskussion :

    1. Wie hier beschrieben , -O2ermutigt die Optimierung den Compiler , die Funktionen, die eingebunden werden können , tatsächlich zu erweitern (Beachten Sie auch, dass dies ohne Optimierungsoptionen Standard-fno-inline ist ). Wie aus dem Ausdruck hier hervorgeht, wurde der tatsächlich inline erweitert (gemäß seiner Definition in dieser bestimmten Übersetzungseinheit), was zu zwei verschiedenen Ausdrucken führte. Trotzdem gibt es immer noch nur eine global verknüpfte Instanz von (wie vom Standard gefordert), wie aus identischen Ausdrucken hervorgeht.fun() fun()fun() &fun
Alaroff
quelle
8
Ihre Antwort ist ein anschaulicher Beitrag darüber, warum die Sprache solche inlineFunktionen zu undefiniertem Verhalten macht.
R Sahu
Sie sollten auch Fälle hinzufügen, in denen das Kompilieren und Verknüpfen getrennt ist, wobei jede .cppeine eigene Übersetzungseinheit ist. Fügen Sie vorzugsweise Fälle für -fltoaktiviert / deaktiviert hinzu.
Syockit
In der C ++ - Referenz heißt es explizit: "Wenn eine Inline-Funktion oder -Variable (seit C ++ 17) mit externer Verknüpfung in verschiedenen Übersetzungseinheiten unterschiedlich definiert ist, ist das Verhalten undefiniert." Das, was Sie geschrieben haben, ist also GCC-spezifisch, da es ein Nebeneffekt der Orchestrierung der Kompilierungs- und Verknüpfungsprozesse ist. Beachten Sie auch, dass dies zwischen den Versionen variieren kann.
Petr Fiedler
27

Sie müssen Ihre Funktion bei der Vorlagenspezialisierung weiterhin explizit einbinden (wenn sich die Spezialisierung in der .h-Datei befindet).

BostonLogan
quelle
21

1) Heutzutage so ziemlich nie. Wenn es eine gute Idee ist, eine Funktion zu integrieren, wird der Compiler dies ohne Ihre Hilfe tun.

2) Immer. Siehe Nr. 1.

(Bearbeitet, um zu reflektieren, dass Sie Ihre Frage in zwei Fragen unterteilt haben ...)

Aric TenEyck
quelle
Ja. Die Inline ist nur ein Hinweis für den Compiler und kann Sie ignorieren. Heutzutage weiß der Compiler wahrscheinlich besser als der Programmierer, welche Funktionen am besten inline sind.
Mark Byers
1
Ja, aber es ist weniger relevant - damit eine Funktion inline ist, muss sich ihr Text in derselben Kompilierungseinheit befinden (z. B. in einem Header). Das ist in C-Programmen weniger verbreitet.
Michael Kohne
1
Das Definieren einer Nicht-Member-Funktionsvorlage (auch als nicht statische Funktionsvorlage bezeichnet) erfordert keine Inline. Siehe eine Definitionsregel (3.2 / 5).
Deft_code
2
-1: inlinewird weiterhin benötigt, um beispielsweise eine Funktion in einer Header-Datei zu definieren (und dies ist erforderlich, um eine solche Funktion in mehrere Kompilierungseinheiten zu integrieren).
Melebius
1
@ Étienne das ist implementierungsspezifisch. Standardmäßig gibt es eine Definitionsregel. Wenn Sie die Funktionsdefinition naiv in mehrere Übersetzungseinheiten aufnehmen, wird ein Fehler angezeigt. Wenn diese Funktion jedoch über inlineeinen Bezeichner verfügt , werden ihre Instanzen vom Linker automatisch zu einer Instanz zusammengefasst, und ODR wird nicht verwendet.
Ruslan
12

Wann sollte ich das Schlüsselwort 'inline' für eine Funktion / Methode in C ++ nicht schreiben?

Wenn die Funktion im Header deklariert und in der .cppDatei definiert ist , sollten Sie dies nicht tun das Schlüsselwort schreiben.

Wann wird der Compiler nicht wissen, wann eine Funktion / Methode 'inline' gemacht werden soll?

Es gibt keine solche Situation. Der Compiler kann keine Funktion inline erstellen. Alles, was es tun kann, ist, einige oder alle Aufrufe der Funktion einzubinden. Dies ist nicht möglich, wenn der Code der Funktion nicht vorhanden ist (in diesem Fall muss der Linker dies tun, wenn er dazu in der Lage ist).

Ist es wichtig, ob eine Anwendung Multithreading ist, wenn man 'Inline' für eine Funktion / Methode schreibt?

Nein, das spielt überhaupt keine Rolle.

Johannes Schaub - litb
quelle
Es gibt Fälle, in denen die Verwendung von Inline in einer CPP-Datei angebracht ist. Beispiel: Optimierungen auf Code anwenden, der vollständig implementierungsspezifisch ist.
Robin Davies
@RobinDavies aktualisierte Antwort. Sie haben anscheinend falsch verstanden, was ich schreiben wollte.
Johannes Schaub - litb
5
  • Wann wird der Compiler nicht wissen, wann eine Funktion / Methode 'inline' gemacht werden soll?

Dies hängt vom verwendeten Compiler ab. Vertrauen Sie nicht blind darauf, dass Compiler heutzutage besser als Menschen wissen, wie man inline ist, und Sie sollten es aus Leistungsgründen niemals verwenden, da es sich eher um eine Verknüpfungsrichtlinie als um einen Optimierungshinweis handelt. Ich stimme zwar zu, dass diese Argumente ideologisch korrekt sind, aber die Begegnung mit der Realität könnte etwas anderes sein.

Nachdem ich mehrere Threads gelesen hatte, versuchte ich aus Neugier die Auswirkungen von Inline auf den Code, an dem ich gerade arbeite, und das Ergebnis war, dass ich eine messbare Beschleunigung für GCC und keine Beschleunigung für Intel Compiler erhielt.

(Weitere Details: Mathematische Simulationen mit wenigen außerhalb der Klasse definierten kritischen Funktionen, GCC 4.6.3 (g ++ -O3), ICC 13.1.0 (icpc -O3); Hinzufügen von Inline zu kritischen Punkten verursachte + 6% Beschleunigung mit GCC-Code).

Wenn Sie also GCC 4.6 als modernen Compiler qualifizieren, ist die Inline-Direktive immer noch wichtig, wenn Sie CPU-intensive Aufgaben schreiben und wissen, wo genau der Engpass liegt.

meda beda
quelle
6
Ich würde gerne mehr Beweise sehen, um Ihre Behauptungen zu stützen. Bitte geben Sie den zu testenden Code sowie die Assembler-Ausgabe mit und ohne Inline-Schlüsselwort an. Eine beliebige Anzahl von Dingen hätte Ihnen Leistungsvorteile bringen können.
void.pointer
1
Endlich jemand, der nicht nur wiederholt, was andere sagen, sondern diese Aussagen tatsächlich überprüft. Gcc betrachtet das Inline-Schlüsselwort in der Tat immer noch als Hinweis (ich denke, Clang ignoriert es vollständig).
MikeMB
@ void.pointer: Warum ist das so schwer zu glauben? Wenn die Optimierer bereits perfekt wären, könnten neue Versionen die Programmleistung nicht verbessern. Aber sie tun es regelmäßig.
MikeMB
3

In Wirklichkeit so ziemlich nie. Alles, was Sie tun, ist vorzuschlagen, dass der Compiler eine bestimmte Funktion inline macht (z. B. alle Aufrufe dieser Funktion / mit ihrem Hauptteil ersetzen). Es gibt natürlich keine Garantien: Der Compiler kann die Direktive ignorieren.

Der Compiler kann solche Dinge im Allgemeinen gut erkennen und optimieren.

DarkSquid
quelle
7
Das Problem ist, dass inlinees in C ++ einen semantischen Unterschied gibt (z. B. in der Art und Weise, wie mehrere Definitionen behandelt werden), was in einigen Fällen wichtig ist (z. B. Vorlagen).
Pavel Minaev
4
Inline wird verwendet, um Fälle zu lösen, in denen ein Symbol mehrere Definitionen hat. Vorlagen werden jedoch bereits von der Sprache verarbeitet. Eine Ausnahme ist eine spezielle Vorlagenfunktion, die keine Vorlagenparameter mehr hat (Vorlage <>). Diese werden eher wie Funktionen als wie Vorlagen behandelt und benötigen daher zum Verknüpfen das Inline-Schlüsselwort.
Deft_code
2

gcc integriert standardmäßig keine Funktionen beim Kompilieren ohne aktivierte Optimierung. Ich weiß nichts über Visual Studio - deft_code

Ich habe dies für Visual Studio 9 (15.00.30729.01) überprüft, indem ich mit / FAcs kompiliert und den Assembly-Code überprüft habe: Der Compiler hat Aufrufe an Mitgliedsfunktionen ohne aktivierte Optimierung erstellt Debug- Modus . Selbst wenn die Funktion mit __forceinline markiert ist , wird kein Inline-Laufzeitcode erzeugt.

Jedzia
quelle
1
Enable / Wall, um zu erfahren, welche Funktionen inline markiert wurden, aber nicht tatsächlich inline wurden
Paulm
0

Sie möchten es ganz am Anfang setzen, bevor Sie den Rückgabetyp eingeben. Aber die meisten Compiler ignorieren es. Wenn es definiert ist und einen kleineren Codeblock enthält, betrachten es die meisten Compiler ohnehin als Inline.

Jeremy Morgan
quelle
0

Sofern Sie keine Bibliothek schreiben oder besondere Gründe haben, können Sie die Optimierung der Verbindungszeit vergessen inlineund stattdessen verwenden. Es entfällt die Anforderung, dass sich eine Funktionsdefinition in einem Header befinden muss, damit sie für das Inlining über Kompilierungseinheiten hinweg berücksichtigt werden kann. Genau das ist esinline ermöglicht.

(Aber siehe Gibt es einen Grund, die Verbindungszeitoptimierung nicht zu verwenden? )

n.caillou
quelle
0

In der Reihe Schlüsselwort fordert den Compiler auf, den Funktionsaufruf durch den Hauptteil der Funktion zu ersetzen. Er wertet zuerst den Ausdruck aus und übergibt ihn dann. Er reduziert den Funktionsaufruf-Overhead, da die Rücksprungadresse nicht gespeichert werden muss und für die Funktion kein Stapelspeicher erforderlich ist Argumente.

Wann zu verwenden:

  • Um die Leistung zu verbessern
  • So reduzieren Sie den Anrufaufwand.
  • Da es sich nur um eine Anfrage an den Compiler handelt, werden bestimmte Funktionen nicht in * große Funktionen eingefügt
    • Funktionen mit zu vielen bedingten Argumenten
    • rekursiver Code und Code mit Schleifen usw.
Blatt
quelle
Es kann für Sie von Vorteil sein zu wissen, dass dies nicht der Fall ist. Die Optimierungsstufe -O0 bis - Ofast bestimmt, ob eine Funktion inline ist oder nicht. Inline bei regulärer Kompilierung (-O0) wird eine Funktion nicht inline, unabhängig davon, ob Sie sie inlinein C und C ++ verwenden oder nicht. C Inline: stackoverflow.com/a/62287072/7194773 C ++ inline: stackoverflow.com/a/62230963/7194773
Lewis Kelsey
0

C ++ Inline unterscheidet sich grundlegend von C Inline .

#include <iostream>
extern inline int i[];
int i [5];
struct c {
  int function (){return 1;} //implicitly inline
  static inline int j = 3; //explicitly inline
};
int main() {
  c j;
  std::cout << i;
}

inlineallein wirkt sich auf den Compiler, Assembler und den Linker aus. Es ist eine Anweisung an den Compiler, dass nur dann ein Symbol für diese Funktion / Daten ausgegeben wird, wenn es in der Übersetzungseinheit verwendet wird, und wenn dies der Fall ist, weisen Sie den Assembler wie Klassenmethoden an, sie im Abschnitt .section .text.c::function(),"axG",@progbits,c::function(),comdatoder .section .bss.i,"awG",@nobits,i,comdatfür Daten zu speichern .

Dies folgt .section name, "flags"MG, @type, entsize, GroupName[, linkage]. Der Abschnittsname lautet beispielsweise .text.c::function(). axGbedeutet, dass der Abschnitt zuweisbar, ausführbar und in einer Gruppe ist, dh ein Gruppenname wird angegeben (und es gibt kein M-Flag, sodass keine Entsize angegeben wird); @progbitsbedeutet, dass der Abschnitt Daten enthält und nicht leer ist; Verknüpfung bedeutet, dass in allen Objektdateien alle Abschnitte mit diesem mit comdat gekennzeichneten Gruppennamen aus der endgültigen ausführbaren Datei entfernt werden, mit Ausnahme von 1, dh der Compiler stellt sicher, dass nur eine Definition in der Übersetzungseinheit vorhanden ist, und weist den Assembler an, diese zu setzen es in seiner eigenen Gruppe in der Objektdatei (1 Abschnitt in 1 Gruppe) und dann stellt der Linker sicher, dass, wenn Objektdateien eine Gruppe mit demselben Namen haben, nur eine in die endgültige EXE-Datei aufgenommen wird. Der Unterschied zwischenc::function()ist der Gruppenname und die Gruppe hatcomdatinlineund nicht verwenden inlineist jetzt für den Assembler und als Ergebnis für den Linker sichtbar, da es nicht im regulären .dataoder gespeichert ist.text vom Assembler aufgrund ihrer Anweisungen usw. .

static inlinein einer Klasse bedeutet dies, dass es sich um eine Typdefinition und nicht um eine Deklaration handelt (ermöglicht die Definition eines statischen Elements in der Klasse) und macht es inline; es verhält sich jetzt wie oben.

static inlineat file scope wirkt sich nur auf den Compiler aus. Für den Compiler bedeutet dies: Geben Sie nur dann ein Symbol für diese Funktion / Daten aus, wenn es in der Übersetzungseinheit verwendet wird, und zwar als reguläres statisches Symbol (speichern Sie in.text /.data ohne die Anweisung .globl). Für den Assembler gibt es jetzt keinen Unterschied zwischen staticundstatic inline

extern inlineist eine Deklaration, die bedeutet, dass Sie dieses Symbol in der Übersetzungseinheit definieren oder einen Compilerfehler auslösen müssen. Wenn es definiert ist, behandeln Sie es als regulär inlineund für den Assembler und Linker gibt es keinen Unterschied zwischenextern inline und inline, daher ist dies nur ein Compiler-Schutz.

extern inline int i[];
extern int i[]; //allowed repetition of declaration with incomplete type, inherits inline property
extern int i[5]; //declaration now has complete type
extern int i[5]; //allowed redeclaration if it is the same complete type or has not yet been completed
extern int i[6]; //error, redeclaration with different complete type
int i[5]; //definition, must have complete type and same complete type as the declaration if there is a declaration with a complete type

Das Ganze oben ohne die Fehlerzeile kollabiert zu inline int i[5] . Natürlich, wenn du es extern inline int i[] = {5};damals getan hastextern würden die explizite Definition durch Zuordnung ignoriert fällig werden.

inlineSehen Sie dies und das in einem Namespace

Lewis Kelsey
quelle
-1

Lassen Sie beim Entwickeln und Debuggen von Code weg inline. Dies erschwert das Debuggen.

Der Hauptgrund für das Hinzufügen besteht darin, den generierten Code zu optimieren. In der Regel wird dadurch mehr Code-Speicherplatz gegen Geschwindigkeit eingetauscht, manchmal wird jedoch inlinesowohl Code-Speicherplatz als auch Ausführungszeit gespart.

Diese Art von Überlegungen zur Leistungsoptimierung vor Abschluss des Algorithmus sind eine vorzeitige Optimierung .

Wallyk
quelle
12
inlineFunktionen werden normalerweise nur dann inline geschrieben, wenn sie mit Optimierungen kompiliert wurden. Sie wirken sich also in keiner Weise auf das Debuggen aus. Denken Sie daran, dass es ein Hinweis ist, keine Forderung.
Pavel Minaev
3
gcc integriert standardmäßig keine Funktionen beim Kompilieren ohne aktivierte Optimierung. Ich weiß nicht über Visual Studio
deft_code
Ich habe an einem riesigen g ++ - Projekt gearbeitet, bei dem das Debuggen aktiviert war. Vielleicht haben andere Optionen dies verhindert, aber die inlineFunktionen wurden eingebunden. Es war unmöglich, einen sinnvollen Haltepunkt in ihnen festzulegen.
Wallyk
2
Durch das Aktivieren des Debuggens wird das Inlining in gcc nicht beendet. Wenn eine Optimierung aktiviert ist (-O1 oder höher), versucht gcc, die offensichtlichsten Fälle zu integrieren. Traditionell hatte GDB Schwierigkeiten mit Haltepunkten und Konstruktoren, insbesondere Inline-Konstruktoren. Dies wurde jedoch in neueren Versionen behoben (mindestens 6.7, möglicherweise früher).
Deft_code
2
Das Hinzufügen inlineträgt nicht dazu bei, den Code eines modernen Compilers zu verbessern, der selbst herausfinden kann, ob er inline ist oder nicht.
David Thornley
-1

Wann sollte man inline:

1.Wenn man den Overhead von Dingen vermeiden möchte, die auftreten, wenn Funktionen wie Parameterübergabe, Steuerübertragung, Steuerungsrückgabe usw. aufgerufen werden.

2.Die Funktion sollte klein sein, häufig aufgerufen werden, und das Inline-Erstellen ist sehr vorteilhaft, da gemäß der 80-20-Regel versucht wird, die Funktion inline zu machen, was einen großen Einfluss auf die Programmleistung hat.

Wie wir wissen, ist Inline nur eine Anforderung an den Compiler, die der Registrierung ähnelt, und kostet Sie bei der Größe des Objektcodes.

Ashish
quelle
"Inline ist nur eine Anfrage an den Compiler, die dem Register ähnelt." Sie sind ähnlich, da weder Anfragen noch etwas mit Optimierung zu tun haben. inlinehat seinen Status als Optimierungshinweis verloren, und die meisten Compiler verwenden ihn nur, um mehrere Definitionen zu berücksichtigen - wie es IMO sollte. Mehr noch, seit C ++ 11 registerwegen seiner früheren Bedeutung von "Ich weiß besser als der Compiler, wie man optimiert" völlig veraltet ist: Es ist jetzt nur ein reserviertes Wort ohne aktuelle Bedeutung.
underscore_d
@underscore_d: Gcc hört immer noch bis inlinezu einem gewissen Grad zu.
MikeMB
-1

Die C ++ - Inline-Funktion ist ein leistungsstarkes Konzept, das häufig für Klassen verwendet wird. Wenn eine Funktion inline ist, platziert der Compiler an jedem Punkt, an dem die Funktion zur Kompilierungszeit aufgerufen wird, eine Kopie des Codes dieser Funktion.

Bei jeder Änderung an einer Inline-Funktion müssen möglicherweise alle Clients der Funktion neu kompiliert werden, da der Compiler den gesamten Code erneut ersetzen müsste, da sonst die alte Funktionalität beibehalten wird.

Um eine Funktion inline zu setzen, setzen Sie das Schlüsselwort inline vor den Funktionsnamen und definieren Sie die Funktion, bevor die Funktion aufgerufen wird. Der Compiler kann das Inline-Qualifikationsmerkmal ignorieren, wenn die definierte Funktion mehr als eine Zeile ist.

Eine Funktionsdefinition in einer Klassendefinition ist eine Inline-Funktionsdefinition, auch ohne Verwendung des Inline-Spezifizierers.

Das folgende Beispiel zeigt anhand der Inline-Funktion maximal zwei Zahlen

#include <iostream>

using namespace std;

inline int Max(int x, int y) { return (x > y)? x : y; }

// Main function for the program
int main() {
   cout << "Max (100,1010): " << Max(100,1010) << endl;

   return 0;
}

Weitere Informationen finden Sie hier .

amirfg
quelle