15 Stimmen

Code in Header-Dateien wird immer inlined?

Ich hatte gerade eine Diskussion mit einem Kollegen über Code in Header-Dateien:

Er sagt, dass Code, der in Header-Dateien definiert ist, immer vom Compiler eingefügt wird (wie der Code der Funktion GetNumber() in meinem Beispiel-Header). Ich sage, dass er manchmal inlined wird, wann immer der Compiler sich dazu entschließt. Wer von uns beiden muss nun einen Kuchen mit zur Arbeit bringen, weil er schmutzige Lügen erzählt? Oder haben wir vielleicht beide Unrecht...?

MyClass.hpp

   class MyClass
    {
    public:
    MyClass();
    ~MyClass();

    int GetNumber() const 
    {
     //...; 
     return m_number;
    };

    private:
    int m_number;
    };

12voto

JoeG Punkte 12744

Jede Funktion, die innerhalb der Klasse definiert (wie Ihr GetNumber-Beispiel) und nicht nur deklariert ist, wird implizit inline . Das bedeutet, dass es gleichbedeutend ist mit der Verwendung des inline Schlüsselwort, so dass mehrere Einschlüsse des Headers nicht zu Verknüpfungsfehlern aufgrund von Mehrfachdefinitionen dieser Funktionen führen.

Die meisten modernen Compiler behandeln inline als Verknüpfungsbefehl und nichts weiter. Einige Compiler bieten stärkere Schlüsselwörter, wie z.B. CL's __forceinline was soviel bedeutet wie "Inline dies, wenn es möglich ist".

Sie haben also sowohl Recht als auch bis zu einem gewissen Grad Unrecht.

7voto

adf88 Punkte 4121

Dein Freund hat Unrecht, du hast Recht.

Das Inlining hängt nicht davon ab, wo sich der Code befindet (Kopfzeile oder nicht). Nach der Vorverarbeitung gibt es keine Kopfzeilen oder Nicht-Kopfzeilen. Die gesamte Einheit ist eine einzige Datei, die alle enthaltenen Elemente enthält.

Versuchen Sie, den gcc-Präprozessor auszuführen, dann werden Sie sehen:

gcc -E some_source_file_with_includes

4voto

Matti Virkkunen Punkte 61148

Das hängt davon ab, was Sie mit "Inlining" meinen. Wenn etwas in einer Header-Datei definiert ist, wird es in jeder Kompiliereinheit, die es enthält, separat kompiliert. Ob eine ruft auf. in die Funktion eingefügt wird, hängt vom Compiler ab.

4voto

liaK Punkte 11212

Eigentlich ist beides richtig. Die Art und Weise, wie ihr es gemeint habt, ist etwas anders. ( Ich denke schon)

Aus der C++-Standarddokumentation für Inline-Funktionen,

  1. Eine Funktionsdeklaration (8.3.5, 9.3, 11.4) mit einem Inline-Spezifizierer deklariert eine Inline-Funktion.

2. Eine Funktion, die innerhalb einer Klassendefinition Definition definiert ist, ist eine Inline-Funktion.

Wie Ihr Kollege sagte, ist es also ist in der Tat eine Inline-Funktion .

Aber die Codesubstitution für die Inline-Funktion anstelle des normalen Funktionsaufrufs ist abhängig vom Compiler . ( Ich hoffe, das ist es, was SIE meinen ) Auch wenn der Compiler keine Ersetzung vornimmt, handelt es sich dennoch um eine Inline-Funktion.

Ich hoffe, das klärt Ihre Bedenken.

2voto

sbi Punkte 211669

Funktion eines Klassenmitglieds definiert (im Gegensatz zu nur erklärt ) in der Definition der Klasse sind implizit inline . Anderer Code in Kopfzeilen ist es nicht.

Sie können dies leicht überprüfen: Erstellen Sie ein kleines C++-Projekt mit einem Header und zwei Implementierungsdateien, definieren Sie eine Funktion

void print(std::ostream& os)
{
  os << "Hello, world!\n";
}

in der Kopfzeile und nehmen Sie diese Kopfzeile in beide Implementierungsdateien auf. Der Linker wird sich nun beschweren, dass die Funktion doppelt definiert ist. Setzen Sie einen inline vor der Funktionsdefinition und der Fehler wird verschwinden.

Es gibt jedoch noch einige weitere Unregelmäßigkeiten. Zum Beispiel erhält eine konstante Definition automatisch eine externe Verknüpfung. Daher wird eine

const int answer = 42;

in einer Kopfzeile führt nicht dazu, dass sich der Linker über mehrere Definitionen von answer , während

int question;

wird.

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