Hallo,
ich habe hier ein mieses Linker-Problem.
Ich habe eine Funktion test(), die ich in test.c geschrieben habe. Im
Header-File test.h steht lediglich der Protyp etwa:
#ifndef TEST_H
#define TEST_H
// --- prototypes
void test(void);
#endif
Die Funktion wird jetzt von zwei *.c-Dateien aus aufgerufen. (timer.c,
pwm.c)
Sie inkludieren beide die test.h, logisch.
Doch irgendwas läuft da noch faul. Einmal inkludieren funktioniert aber.
Mehrmals leider nicht.
ERROR: The following symbols referenced could not be resolved...
Kann ich das irgendwie mit dem Schlüsselwort extern umgehen oder wie
löse ich das Problem?
DANKE schon einmal.
>Gehört das extern denn auch mit in die test.c oder nur bei den>Prototypen?
Ich mache das so, dass ich alle Prototypen in einer header-Datei packe
und diese dann "inkludiere". Jeder Prototyp bekommt dann extern. So hast
du wenigstens alle Funktionen an einem Ort versammelt.
Das kannst du nicht mit extern umgehen. Du hast scheinbar einmal
vergessen die test.o mit reinzulinken, daher findet er die Funktion beim
Linken dann nicht.
Beispiel:
#include "define_prototypes.h"
extern void timer_init(void);
-------------------------
Datei main.c
void main(void)
{
timer_init();
}
---------------------------
Datei init.c
void timer_init(void)
{
...
}
So machst du das z.B. auch, wenn du delays einbauen möchtest. Dann
definierst du z.B. in der Datei delay.c deine Funktion, packst sie in
die prototypen-Datei mit extern rein und inkludierst in jedem c-File
diese Datei. Dann kannst du sie überall aufrufen.
PS: Ohne Extern erhälst du die Fehlermeldung "implicit declaration of
function...". Dein Compiler kann nicht "riechen", wo sich deine Funktion
befindet. Somit ist extern hier essentiell wichtig.
Das extern an dieser Stelle schadet zwar nicht, bringt
aber auch nichts.
Der Compiler kann auch so erkennen das es sich um eine
Deklaration handelt.
Wenn schon, dann mach es richtig:
Datei: Proto.h
*************
Gast wrote:
> PS: Ohne Extern erhälst du die Fehlermeldung "implicit declaration of> function...". Dein Compiler kann nicht "riechen", wo sich deine Funktion> befindet. Somit ist extern hier essentiell wichtig.
Mit Verlaub: Aber du verzapfst Blödsinn.
extern ist hier fehl am Platz, dat hilft nix. Welcher Compiler?
Denn bei Funktionsprototypen ist ja extern idR eh default.
It can be used as a stylistic hint to indicate that the
function's definition is probably in another source file, but
there is no formal difference between
extern int f();
and
int f();
References: ANSI Sec. 3.1.2.2, Sec. 3.5.1; ISO Sec. 6.1.2.2,
Sec. 6.5.1; Rationale Sec. 3.1.2.2; H&S Secs. 4.3,4.3.1 pp. 75-
6.
Ich tippe auch auf Linker Problem
@ GAST
Das ist absolut richtig was du da schreibst, doch irgendwie ist mein
Linker echt zu dumm. Mit extern vor jedem PROTOTYP hat nix gebracht.
Echt übel.
Sven
Nochmal: Gast löst ein Problem, welches nicht existiert.
Dein Problem besteht höchst wahrscheinlich darin, dass du
vergessen hast, das zweite Source Code File deiner IDE oder
deinem makefile bekannt zu machen.
Alternativ könnte es auch ein simpler Tippfehler im Funktions-
namen sein.
'undefined reference' ist eine Fehlermeldung vom Linker und
nicht vom Compiler.
>Das ist absolut richtig was du da schreibst, doch irgendwie ist mein>Linker echt zu dumm. Mit extern vor jedem PROTOTYP hat nix gebracht.>Echt übel.
Hast du ein selbst geschriebenes Make-File? Ein Linker kann nicht zu
dumm sein. Zeig mal bitte dein Make-File.
Sir Sydom wrote:
> extern ist hier fehl am Platz, dat hilft nix. Welcher Compiler?> Denn bei Funktionsprototypen ist ja extern idR eh default.
Rüchtüch. extern hat nur bei Variablen einen Effekt, weil der Compiler
da nicht selber zwischen Deklaration und Definition unterscheiden kann.
Bei Funktionsprototypen ist extern ziemlich sinnfrei.
Gast wrote:
>>Mit Verlaub: Aber du verzapfst Blödsinn.>> Mit Verlaub, du musst nicht deine primitive Geisteshaltung zeigen und> jeden gleich anpissen.
Und du musst hier nicht noch weiter Mist erzählen obwohl es schon
nachweislich widerlegt worden ist (Sir Sydoms Zitat)
Gast wrote:
>>Mit Verlaub: Aber du verzapfst Blödsinn.>> Mit Verlaub, du musst nicht deine primitive Geisteshaltung zeigen und> jeden gleich anpissen.
Es geht nicht um anpissen.
Es geht darum, dass Sven ein ganz anderes Problem hat, als das
was du die ganze Zeit zu lösen versuchst (und das in Wirklichkeit
kein Problem ist).
Und dein Erklärung von 'extern' zeigt eigentlich nur, dass du
selbst 'extern' nicht richtig verstanden hast.
> Zeig mal bitte dein Make-File.
Endlich gehts in die richtige Richtung.
?
Das erste ist ein PROTOTYP. Das heist das sagt dem Compiler "du, da
fliegt irgendwo 'ne Funktion rum die so aussieht - die Funktion selber
liegt aber ganz woanders, daher sag ich dir mal wie die aufgerufen
werden muss".
Das zweite ist kein Prototyp. Da wird eine Variable definiert, so wie
man eine Funktion implementiert.
Da die Variable aber auch woanders liegen kann, braucht man auch für
Variablen Prototypen - das sieht dann so aus:
I_ H. wrote:
> Das erste ist ein PROTOTYP.
Zufällig auch das. ;) In erster Linie ist es aber eine
Funktionsdeklaration. Man kann eine solche auch ohne einen
Prototypen schreiben:
int dummy1();
Das Schlüsselwort "extern" ist bei Funktionsdeklarationen
wahlfrei, da der Compiler aus dem Kontext (rundes Klammernpaar
mit abschließendem Semikolon) ableiten kann, dass es sich um
eine Funktionsdeklaration handelt.
> Das zweite ist kein Prototyp.
Kann es auch nicht sein, da das Wort "Prototyp" in C nur für
Funktionen benutzt wird.
> Da wird eine Variable definiert, so wie> man eine Funktion implementiert.
Ja.
> Da die Variable aber auch woanders liegen kann, braucht man auch für> Variablen Prototypen - das sieht dann so aus:
1
externintdummy2;
Das ist richtig geschrieben, aber falsch bezeichnet. Es ist
eine Variablendeklaration. (Zur Erinnerung: das andere da oben
war eine Variablendefinition.)
Es ging mir auch darum zu erklären wie was wozu benutzt wird, und nicht
die exakten Begriffe zu verwenden, die mehr Verwirrung stiften als das
sie weiterhelfen ;).
Die begriffliche Unterscheidung zwischen Deklaration, Definition und
Prototyp halte ich dennoch für essenziell genug, als dass eine
(öffentlich lesbare und daher potenziell von anderen als Referenz
benutzte) Erklärung dafür korrekt sein sollte. Es ist ja nicht nur,
dass man das Prinzip verstanden haben muss. Wenn man diese drei
Begriffe gedanklich nicht richtig sortiert, wird man zu gegebener
Zeit aus einer möglichen Fehlermeldung des Compilers (wie bspw.
"Function declaration is not a prototype") absolut nicht schlau.