C99-Inline-Funktion in .c-Datei

Lesezeit: 4 Minuten

Benutzeravatar von user14416
Benutzer14416

Ich habe meine Funktion in .c (ohne Header-Deklaration) wie hier definiert:

inline int func(int i) {
 return i+1;
}

Dann verwende ich es in derselben Datei unten:

...
i = func(i);

Und während des Verlinkens bekam ich “undefinierter Verweis auf ‘func'”. Wieso den?

  • Entweder schaffe es static oder geben Sie eine Nicht-Inline-Definition an, die der Linker finden kann.

    – Daniel Fischer

    26. April 2013 um 21:39 Uhr

  • Siehe auch stackoverflow.com/questions/6312597

    – Jens

    26. April 2013 um 21:44 Uhr

Benutzeravatar von Jens Gustedt
Jens Gustedt

Das inline Das Modell in C99 ist etwas anders als die meisten Leute denken, und insbesondere anders als das von C++ verwendete

inline ist nur ein Hinweis, damit sich der Compiler nicht über doppelt definierte Symbole beschwert. Es garantiert nicht, dass eine Funktion eingebettet ist, noch dass ein Symbol generiert wird, wenn es benötigt wird. Um die Generierung eines Symbols zu erzwingen, müssten Sie eine Art Instanziierung hinzufügen nach das inline Definition:

int func(int i);

Normalerweise hättest du die inline Definition in einer Header-Datei, die dann in mehreren .c-Dateien (Kompilierungseinheiten) enthalten ist. Und Sie hätten die obige Zeile nur in genau einer der Kompilierungseinheiten. Sie sehen wahrscheinlich nur das Problem, das Sie haben, weil Sie keine Optimierung für Ihren Compilerlauf verwenden.

Also, Ihr Anwendungsfall, den zu haben inline in der .c-Datei macht nicht viel Sinn, besser einfach verwenden static dafür sogar ein zusätzliches inline kauft dir nicht viel.

  • mein schlecht, ein extern Dateibereichsdeklaration ohne inline tut Erzwingen Sie, dass die Definition keine Inline-Definition ist

    – Christoph

    27. April 2013 um 17:04 Uhr

  • Ich habe eine Frage, warum tritt diese Situation auf, wenn die Optimierung deaktiviert ist? Wenn ich es mit der Option gcc -O1 einschalte, wird es nur kompiliert. Welche Option in der gcc-Optimierung sorgt dafür, dass dieser Code richtig kompiliert wird?

    – Lazureus

    1. November 2013 um 0:13 Uhr

  • @Lazureus, wenn du mit kompilierst -O0, ich nehme an, Sie meinen, dass gcc normalerweise keine Funktion enthält. Also dann du muss die Symbole irgendwo definiert haben, sonst würde es keines finden inline deklarierte Funktionen.

    – Jens Gustedt

    1. November 2013 um 8:16 Uhr

  • Wird der Prototyp wirklich benötigt? nach? Ich habe einige Tests durchgeführt, die meine Überzeugung zu bestätigen scheinen, dass es sich um einen Prototyp handelt Vor die Definition erzwingt auch die Symbolerzeugung. Laufen Sie einfach und sehen Sie: echo "int f(void); inline int f(void){return 42;}" | cc -x c -Wall -Wextra -Wpedantic -pedantic-errors -Werror -O3 -std=c99 -S - -o -. Ist das eine Erweiterung des Standards (oder eine Fehlinterpretation in gcc)?

    – alx

    15. Juni um 10:25 Uhr


Benutzeravatar von Christoph
Christoph

Die Inline-Semantik von C99 wird oft missverstanden. Das inline Der Bezeichner dient zwei Zwecken:

Zunächst als Compiler-Hinweis im Falle von static inline und extern inline Erklärungen. Die Semantik bleibt unverändert, wenn Sie den Bezeichner entfernen.

Zweitens im Falle von roh inline (also ohne static oder extern), um eine Inline-Definition als Alternative zu einer externen bereitzustellen, die in einer anderen Übersetzungseinheit vorhanden sein muss. Das Nichtbereitstellen des externen ist ein undefiniertes Verhalten, das sich normalerweise als Verbindungsfehler manifestiert.

Dies ist besonders nützlich, wenn Sie eine Funktion in eine gemeinsam genutzte Bibliothek stellen, aber auch den Funktionsrumpf für Optimierungen (z. B. Inlining oder Spezialisierung) verfügbar machen möchten. Einen ausreichend intelligenten Compiler vorausgesetzt, ermöglicht Ihnen dies, viele der Vorteile von C++-Vorlagen wiederzugewinnen, ohne durch Präprozessor-Hoops springen zu müssen.

Beachten Sie, dass es etwas chaotischer ist, als ich hier beschrieben habe, da eine andere nicht-inline externe Deklaration des Dateibereichs den ersten Fall auslöst, wie in Jens ‘Antwort beschrieben, auch wenn die Definition selbst dies ist inline Anstatt von extern inline. Dies ist so beabsichtigt, dass Sie eine einzelne Inline-Definition in einer Header-Datei haben können, die Sie in die Quelldatei einschließen können, die die externe Definition bereitstellt, indem Sie eine einzelne Zeile für die externe Deklaration hinzufügen.

  • Diese Antwort ist etwas veraltet – ich dachte, es gäbe einen Fehler in Jens’ Antwort, aber es stellte sich heraus, dass ich mich geirrt habe …

    – Christoph

    27. April 2013 um 17:21 Uhr


  • Tatsächlich ist es (zumindest für mich) eine wertvolle Antwort, zu erklären, wann semantisch nützlich ist.

    – Vorac

    24. Februar 2014 um 12:04 Uhr

Benutzeravatar von Niloy Rashid
Niloy Rashid

Dies liegt an der Art und Weise, wie GCC die Inline-Funktion handhabt. GCC führt im Rahmen der Optimierung eine Inline-Substitution durch.

Um diesen Fehler zu entfernen, verwenden Sie static vor Inline. Verwenden static Schlüsselwort zwingen den Compiler, diese Funktion einzubetten, wodurch das Programm erfolgreich kompiliert wird.

static inline int func(int i) {
 return i+1;
}
...
i = func(i);

  • Aber wie geht man mit Mitgliedsfunktionen um?

    – Piroxiljin

    6. März 2019 um 7:53 Uhr

  • @Piroxiljin: C hat keine Memberfunktionen, nur C++ hat das. Laut der Antwort von Jens auf diese Frage ist die Bedeutung von inline unterscheidet sich zwischen C und C++.

    – Peter Cordes

    8. August 2020 um 13:53 Uhr


  • Hm. Was ist denn hier los? Ich dachte immer static und inline waren aus irgendeinem Grund orthogonal. Wie in, static impliziert, dass es vorhanden sein muss, während inline (per Definition) nicht. (mit “nicht vorhanden” meine ich als definiertes Symbol, da es eingebettet gewesen wäre).

    – sherrelbc

    11. November 2020 um 11:14 Uhr


1414540cookie-checkC99-Inline-Funktion in .c-Datei

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy