Hallo zusammen Ich habe in C eine Inline Definierung in einem Header. Im main.c habe ich das Headerfile eingebunden. Wenn ich jedoch kompilieren will, zeigt es mir an, dass es mehrmals definiert ist. Verschiebe ich die Definition jedoch ins main.c, ist der Code kompilierbar. Danke für Lösungsansätze. MfG
:
Verschoben durch User
TM F. schrieb: > Danke für Lösungsansätze. in den Fehlermeldung steht doch do, wo es mehrfach vorhanden ist. Include guard vorhanden?
Peter II schrieb: > in den Fehlermeldung steht doch do, wo es mehrfach vorhanden ist. Es zeigt mir nicht an, wo weitere Definitionen sind und wenn ich die Namen ändere, bleiben die Fehlermeldungen.
:
Bearbeitet durch User
Alter Compiler der noch kein richtiges inline kann? Deine Fehlermeldung ist vom Linker nehm ich mal an?
TM F. schrieb: > Es zeigt mir nicht an, wo weitere Definitionen sind und wenn ich die > Namen ändere, bleiben die Fehlermeldungen. dann zeige uns doch mal die Fehlermeldung
TM F. schrieb: > Hier kann du den text nicht mal ohne bild posten, am besten sogar wo man die erste spalte vollständig sieht?
Wie soll man da wirklich was sehen? Ok, der Compiler sagt definition, nicht declaration, also vielleicht wie Peter II schrieb: Peter II schrieb: > Include guard vorhanden?
Vllt meint man: static inline Damit wird die Funktion nicht an den linker weitergereicht
Die Fehlermeldungen sind offensichtlich vom Compiler also wirds ein Problem wegen fehlender Include Guards sein.
Sebastian V. schrieb: > Die Fehlermeldungen sind offensichtlich vom Compiler also wirds ein > Problem wegen fehlender Include Guards sein. Nop multiple definition" ist immer vom Linker. Da fehlt ein 'static' vorm 'inline'. Ohne wird der Compiler auf jeden Fall auch eigenständige Implementierungen für die Funktionen erzeugen, weil er nicht davon ausgehen kann, dass sie quer durch das Programm überall geinlined werden. Mit static kann er davon ausgehen, dass dem so ist.
Karl H. schrieb: > Da fehlt ein 'static' vorm 'inline'. Genau, dies hat mein Problem gelöst :) Danke für die Hilfe
Karl H. schrieb: > Nop > multiple definition" ist immer vom Linker. > > Da fehlt ein 'static' vorm 'inline'. Ah hab mich von den Zeilennummern verwirren lassen. Wenn man nicht mit Debug Informationen Compiliert kriegt man nicht so schön Ausgaben. Trotzdem ist es ein merkwürdiger Fehler vom Compiler. Inline Funktionen im Header sind korrekt und sollten auch ohne static davor compilieren (tun sie bei mir auch).
Sebastian V. schrieb: > Karl H. schrieb: >> Nop >> multiple definition" ist immer vom Linker. >> >> Da fehlt ein 'static' vorm 'inline'. > > Ah hab mich von den Zeilennummern verwirren lassen. Wenn man nicht mit > Debug Informationen Compiliert kriegt man nicht so schön Ausgaben. > > Trotzdem ist es ein merkwürdiger Fehler vom Compiler. Inline Funktionen > im Header sind korrekt und sollten auch ohne static davor compilieren > (tun sie bei mir auch). Compilieren tun sie. Das ist auch nicht das Problem. Aber: da der Compiler nicht davon ausgehen kann, dass an allen Stellen geinlined wird, muss er auch eine freistehende Defintion dieser Funktion erstellen. Du könntest dich ja aus einem ganz anderen C-File mittels explizitem 'extern' auf diese Funktion beziehen. Ein 'static' davor begrenzt aber den Scope dieser Funktion auf jeden Fall auf das C-File, in welches diese inline Definition hineingezogen wurde. D.h. in diesem Fall ist es prinzpiell nicht möglich, dass sich irgendwelcher anderer Code mittels 'extern' auf diese Funktion beziehen könnte. Der Compiler kennt weiss also, dass in diesem Fall er beim Compilieren dieses einen C-Files alle Stellen gesehen hat, an der diese Funktion benutzt wurde. Und da er die alle geinlined hat, braucht es die freistehende Funktion nicht. main.c
1 | extern void bar(); |
2 | |
3 | inline void foo() |
4 | {
|
5 | mach was .... |
6 | }
|
7 | |
8 | int main() |
9 | {
|
10 | foo(); // dieser Aufruf wird geinlined |
11 | bar(); |
12 | }
|
help.c
1 | extern void foo(); |
2 | |
3 | void bar |
4 | {
|
5 | foo(); // aber dieser Aufruf nicht. Daher muss es neben der |
6 | // direkten Ersetzung in main.c auch noch eine tatsächlich
|
7 | // aufrufbare Version der Funktion geben.
|
8 | }
|
Das ist das eigentliche Problem, wie es dazu kommt, dass der Compiler bei jedem #include (mit den inline-Funktionen) in jeder Compilation-Unit eine weitere Version der Funktion erzeugen muss. Und nochmal: Der Fehler stammt nicht vom Compiler sondern vom Linker, der bei der Endmontage der Einzelteile bemerkt, dass es eine (tatsächliche) Funktion dieses Namens ein paar mal gibt. In jedem C-File, welches vom Compiler einzeln übersetzt wurde, sind dieselben Funktionen jedesmal als tatsächlich aufrufbare Funktionen erneut angelegt worden.
:
Bearbeitet durch User
Jörg W. schrieb: > Nein. C99-Semantik. Sicher? Ich habe gerade nochmal rumgespielt und ich kann das Problem vom TO nur nachvollziehen wenn ich mit -std=gnu89 compiliere. Mit -std=c99 und -std=c11 erhalte ich statt "multiple definition" ein "undefined reference to" Fehler beim Linken. Der C99 Standard sagt dazu: If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition. An inline definition does not provide an external definition for the function, [...] Wenn ich das richtig verstehe, dann besagen diese Zeile das in dem Fall vom TO, also nur inline im Header, KEINE externe Definition bereitgestellt wird und ich damit auch keinen "multiple definition" Fehler kriege. Stattdessen kriege ich "undefined reference to" weil gar nichts extern definiert wird, sofern man das nicht einmal explizit macht.
Sebastian V. schrieb: > An inline definition does not provide an external definition for the > function, [...] Stimmt, dann hab' ich das verwechselt. Karl-Heinz hat die Erklärung ja geliefert.
Karl Heinz behauptet aber auch, dass bei jeder inline Definition eine externe Definition erzeugt wird: Karl H. schrieb: > Das ist das eigentliche Problem, wie es dazu kommt, dass der Compiler > bei jedem #include (mit den inline-Funktionen) in jeder Compilation-Unit > eine weitere Version der Funktion erzeugen muss. Das scheint aber auch nur auf die GNU 89 Variante von C zuzutreffen.
Sebastian V. schrieb: > Das scheint aber auch nur auf die GNU 89 Variante von C zuzutreffen. Ja, schließlich war ‘inline’ in C89 selbst noch nicht definiert, erst in C99. Jedenfalls ist man mit ‘static inline’ immer auf der sicheren Seite. Wenn der Compiler die Funktion nicht inline auflöst, verplempert man allerdings Platz.
Jörg W. schrieb: > Wenn der Compiler die Funktion nicht inline auflöst, verplempert man > allerdings Platz. Mit -Winline wird man vom GCC gewarnt, falls dies der Fall ist.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.