2016-06-14 13 views
0

Ich habe eine Klasse in Header-Datei definiert und implementiert seine Funktion in der gleichen Header-Datei. Ich habe kein Inline-Schlüsselwort mit Funktionsdefinition angegeben, weil ich denke, dass der Compiler es standardmäßig als Inline-Funktion betrachten wird - aber Inline ist nur ein Hinweis auf den Compiler, richtig? Was, wenn der Compiler es wegen seiner Länge nicht als Inline-Funktion betrachtet? Ich bekomme nie die Fehlermeldung "Mehrfachdefinitionen" in der Realität.Kann ein sehr langes Klassenfunktionsmember in der Headerdatei definiert werden?

struct tmp { 
    void print() { 
     ...(very long) 
    } 
}; 
+2

Warum? Möchten Sie wirklich, dass der Compiler den gesamten Code jedes Mal kompiliert, wenn die Datei enthalten ist? Was ist der Zweck? – EJP

+0

Der Compiler macht das nicht, @ejp, vorausgesetzt, der Programmierer ist kompetent genug, um Include-Wächter zu verwenden. –

+0

@EJP Nur für Neugier und manchmal kleine Funktion wird größer und größer. –

Antwort

2

habe ich mit Funktionsdefinition setzen Inline-Schlüsselwort nicht, weil ich denke, es ist Compiler als Inline-Funktion standardmäßig in dem Körper einer Klasse definiert

Ja, Member-Funktionen betrachten wird. Das Schlüsselwort ist nicht notwendig.

Inline ist nur ein Hinweis auf Compiler, oder? Was, wenn der Compiler es wegen seiner Länge nicht als Inline-Funktion betrachtet?

Ja, irgendwie. Tatsächlich hat das Schlüsselwort inline zwei Bedeutungen.

Der erste ist der, an den Sie denken, derjenige, der dem Optimierer vorschlägt, den Code im Funktionskörper an der Aufrufstelle einzubinden. Wie Sie bereits sagten, ist dies nur ein Hinweis - der Optimierer kann diese Anfrage ignorieren, wenn er feststellt, dass es sich um eine Leistungspessimierung handelt (oder wenn er aus einem anderen technischen Grund nicht in der Lage ist). Diese Bedeutung des Inline-Schlüsselworts ist wohl obsolet. Alle optimierenden Compiler ignorieren heutzutage das Inline-Schlüsselwort, weil ihre Autoren ihre Heuristiken für klüger halten als den Programmierer. Dies ist fast immer der Fall, so dass es ziemlich sinnlos ist, den Optimierer zu versuchen, indem Sie Ihre Funktionen inline markieren.

Die zweite Bedeutung des Inline-Schlüsselworts besteht darin, die One-Definition-Regel (ODR) zu lockern, so dass mehrere Definitionen der gleichen Funktion für den Linker zulässig sind. (Obwohl das Verhalten des Linkers unter solchen Umständen ein Implementierungsdetail ist, werden die meisten nur willkürlich eine der Definitionen auswählen. Was natürlich nur dann gut funktioniert, wenn sie alle gleich sind.) Diese Bedeutung des Inline-Schlüsselwortes ist immer noch sehr wichtig, und erklärt, warum es heute noch in Code verwendet wird.

Dies ist die Bedeutung, von der Ihr Code profitiert. Da Elementfunktionen, die im Rumpf einer Klasse definiert sind, implizit als Inline gekennzeichnet sind, erhalten Sie keine mehrfach definierten Symbolfehler vom Linker.

Wenn Sie die Funktion in der Header-Datei definiert hatte, aber nicht innerhalb der Klassendefinition in anderen Worten, wenn Sie dies getan hatte:

struct tmp { 
    void print(); 
}; 

void tmp::print() 
{ ... } 

dann starten Sie das mehrfach definiert Symbol bekommen Fehler, sobald diese Header-Datei in zwei oder mehr Compilanden enthalten war (dh, Übersetzungseinheiten). Hier müssen Sie das Schlüsselwort inline zur Definition der Funktion hinzufügen, nicht weil Sie möchten, dass der Compiler es "inline" macht, sondern weil Sie sich von der ODR befreien wollen.

+0

Also 'Inline' für kleine Funktionen definiert nur einmal keinen Sinn? –

+0

@lw Die zwei Bedeutungen des Schlüsselworts 'inline' können nicht so einfach auseinander gezogen werden. Es ist nicht sinnvoll, eine Funktionsdeklaration als Inline zu kennzeichnen, es sei denn, die Deklaration und die Definition sind identisch, so dass Sie niemals eine Inline-Funktion haben können, die nur einmal definiert ist. Sie müssen im Prinzip * immer * inline verwenden, wenn Sie eine Funktion in der Header-Datei definieren (entweder explizit oder implizit). Das ist ein weiterer Grund, warum der Optimierer Inline generell als Optimierungshinweis ignoriert und nur das tut, was er tun möchte. Hören Sie auf, über Inline als Optimierung nachzudenken; Es umgeht nur ODR. –

0

EDIT @Leon (unten) angegeben, dass meine Antwort (reproduziert unten) war nicht richtig. Die richtige Antwort ist beschrieben here - kurz gesagt, wenn der Compiler entscheidet, eine Funktion nicht inline zu machen, wird es immer noch in das Objektmodul eingefügt. Aber der Linker wird dann eine der (möglicherweise vielen) Kopien in den verschiedenen Modulen auswählen und alle anderen verwerfen.


Sie haben Recht: Sie werden nicht die „multiple Definition“ Fehlermeldung erhalten, weil jedes Mal, wenn der Compiler entscheidet nicht eine Funktion inline setzen, macht es die Funktion static innerhalb des aktuellen Moduls. Das bedeutet, dass Sie eine große Anzahl von Kopien Ihrer großen Funktion über Ihren Code verteilt haben könnten. sind implizit inline

+1

Das stimmt nicht. Siehe http://stackoverflow.com/questions/4193639/inline-function-linkage/4193698#4193698 – Leon

+0

Wow. Du lernst jeden Tag etwas Neues. Ich wusste, dass die Inline-Funktion in jedem Modul war, in das sie kompiliert wurde. Ich wusste nicht, dass der Linker einen auswählte und alle anderen entfernte. –

+0

In dieser Frage erscheint der Fehler "Mehrfachdefinition" http://stackoverflow.com/questions/30803019/when-we-define-a-class-member-function-in-header-file-of-that-class-then- Inline Also ich denke Position ist wichtig .. –

Verwandte Themen