Hey, Ich bin hier am verzweifeln weil ich bei meinem Program immer wieder den gleichen Fehler bekomme. Also Ich hab ein Programm da läuft es problemlos und bei meinem neuen geht es nicht! Ich habe folgendes: MAIN.H #include <avr/io.h> #include <avr/interrupt.h> TIMEB.H extern int i; void timeb_init(void) TIMEB.C #include "timeb.h" #include "main.h" int i=0; void timeb_init(void) { tralala.... } MAIN.C #include "main.h" #include "timeb.h" int main(void) { timeb_init(); for(;;){} return 0; } Jetzt bekomme ich immer die Fehlermeldung: Build started 2.6.2008 at 16:35:19 avr-gcc.exe -mmcu=atmega32 MAIN.o TIMEBASE.o -o Timeing_neu.elf MAIN.o: In function `main': ../MAIN.c:6: undefined reference to `timebase_init' make: *** [Timeing_neu.elf] Error 1 Build failed with 1 errors and 0 warnings... Hab schon diverse Beiträge gelesen aber keiner hat so wirklich weiter geholfen. Vielleicht hat einer einen Beitrag der Hilft oder kann mir das schnell schildern. Also ich benutze AVR Studio und WinAvr. Mein Makefile wird automatisch erstellt. Wenn ich das öffne und mit dem Makefile meines vorrigen programmes vergleiche sehe ich keine Unterschiede. Mit Rechtsklick auf source kann ich options auswählen. da hab ich standartmässig [all files] markiert..... Danke schon mal für jedweilige Tipps
loki81 wrote: > Ich habe folgendes: Das sieht erst mal auch gut aus > MAIN.o: In function `main': > ../MAIN.c:6: undefined reference to `timebase_init' Poste bitte deinen wirklichen Code. Der Linker findet die Funktion timerbase_init nicht. Die ist in dem von dir geposteten weder vorhanden noch wird sie aufgerufen. PS: Das ganze hat nichts mit #include zu tun.
oh.... sorry Hab das im beitrag eben abgekürzt und nicht daran gedacht, das ich die Fehlermeldung kopieren wollte. Also überall wo hier "timeb" steht habe ich im Programm timebase stehen. Also hier aber noch mal der Code und das M-File sollte auch dran sein
Hey, Also ich habe mein altes Programm genommen alles rausgeschmissen und genau die gleiches Textzeilen rein wie im neuen. Dann hab ich gerade beide Makefiles nebeneinander gestellt und der einzige Unterschied den ich gefunden habe war MAIN.c MAIN.C daran hat es dann auch gelegen!!! Jetzt aber habe garnicht ich die MAIN.c erstellt sondern AVR-Studio. Nur aus Interersse kann mir jemand sagen warum das so nicht geht? und warum motzt er dann wegen einer include? Vielen lieben Dank für den Tipp
Er motzt doch gar nicht wegen dem include, sondern weil er die Funktion timebase_init nicht finden kann. Grund: MAIN.c -> C-Source TIMEBASE.C -> C++-Source Wegen des "name mangling" bei C++ hat die Funktion dann in den beiden Object-Files unterschiedliche Namen.
Das geschieht aber eigentlich nur auf unixoiden OS*, unter Windows ist das ein Fehler in der Portierung des Compilers resp. von make. Eine Unterscheidung von Dateinamen anhand von Groß- und Kleinschreibung ist unter Windows nicht zulässig. Anwendungen für Windows müssen "main.c", "MAIN.c", "main.C" und weitere Permutationen als identisch behandeln. *) Linux, BSD, Solaris etc. Und Mac OS, sofern das "case-sensitive" HFS+ verwendet wird, was nicht die Standardeinstellung ist.
Rufus t. Firefly wrote: > Eine Unterscheidung von Dateinamen anhand von Groß- und Kleinschreibung > ist unter Windows nicht zulässig. > Anwendungen für Windows müssen "main.c", "MAIN.c", "main.C" und weitere > Permutationen als > identisch behandeln. "nicht zulässig" und "müssen"? Hat Bill Gates das per Gesetz festlegen lassen? Ich würde "nicht zulässig" durch "nicht zweckmäßig" und "müssen" durch "sollten" ersetzen.
Auch wenn man es kaum glauben mag, hat doch Microsoft auch gewisse Beschreibungen ihrer Betriebssysteme herausgegeben, und die enthalten unter anderem auch wie Dateisysteme mit Dateinamen umgehen. Nein, es ist ein Fehler. # Do not assume case sensitivity. For example, consider the names OSCAR, Oscar, and oscar to be the same, even though some file systems may consider them as different. (Quelle: http://msdn.microsoft.com/en-us/library/aa365247.aspx)
Den C-Compiler interessiert's auch einen feuchten Kehrricht, ob die Datei auf der Platte als Foo.C oder FOO.C oder foo.c abgelegt ist. Mit allen drei Namen würde er bei Win32 die gleiche Datei öffnen. Das einzige, was ihn interessiert ist, ob du auf seiner Kommandozeile ein .c oder ein .C hinschreibst. Daran entscheidet er (in Abwesenheit von -x language=XXX), welches Compiler-Frontend für diese Datei gewünscht wird. Dass der GCC nach MSDN-Regeln geschrieben worden wäre, hat nie jemand behauptet. Dann müsste er vermutlich auch Schrägstriche für die Optionen benutzen...
@ loki81: Es gibt in TIMEB.C und MAIN.C ein include von TIMEB.H. TIMEB.H:
1 | extern int i; |
2 | void timeb_init(void) /*für TIMEB.C OK*/ |
Für MAIN.C müßte es aber folgendermaßen aussehen:
1 | extern void timeb_init(void); |
Tschau Sven!
Sven Woehlbier wrote: > Für MAIN.C müßte es aber folgendermaßen aussehen: > >
1 | > extern void timeb_init(void); |
2 | >
|
Falsch. Es muss gar nicht.
1 | void timeb_init(void); |
tut exakt dasselbe, oder was sollte daran aus Sicht des Compilers anders funktionieren?
@ Jörg Wunsch: Das interessiert nicht den Compiler sondern den Linker. in MAIN.C steht durch include <timeb.h>
1 | void timeb_init(void); |
Wenn der Funktionskopf in MAIN.C auf diese Weise definiert ist, muß die Funktion in MAIN.C implementiert sein. Das Schlüsselwort "extern" vor dem Funktionskopf bewirkt, daß die Implementation der Funktion timeb_init() nicht nur in dem Objektfile MAIN.O sondern auch in den anderen Objektfiles gesucht wird. siehe Fehlermeldung: Build started 2.6.2008 at 16:35:19 avr-gcc.exe -mmcu=atmega32 MAIN.o TIMEBASE.o -o Timeing_neu.elf !!!!!MAIN.o: In function `main': !!!!!! ../MAIN.c:6: undefined reference to `timebase_init' make: *** [Timeing_neu.elf] Error 1 Build failed with 1 errors and 0 warnings... Laut Fehlermeldung wird die Funktion in MAIN.O nicht gefunden. Wie auch, wenn sie in TIMEB.C steht. Tschau Sven!
> Wenn der Funktionskopf in MAIN.C auf diese Weise definiert ist, muß die > Funktion in MAIN.C implementiert sein. Das ist nicht korrekt, denn Funktionen sind implizit als extern deklariert, es sei denn, das Schlüsselwort static würde verwendet.
@ Rufus t. Firefly: Ich habe mein letztes Posting nocheinmal editiert, während Du Deine Antwort geschrieben hast (siehe Fehlermeldung). Wenn das stimmen sollte, was Du geschrieben hast, dann sollte es nicht zu der Fehlermeldung kommen! Also ich habe es jedenfalls so gelernt wie ich es geschrieben habe. Allerdings habe ich vor 1999 Studiert. Hat sich da was mit den Standards C98 und/oder C99 geändert? Tschau Sven!
Sven Woehlbier wrote: > Wenn das stimmen sollte, was Du geschrieben hast, dann sollte es nicht > zu der Fehlermeldung kommen! Es stimmt aber, und die Fehlermeldung ist keine vom Compiler (dem war/ist nämlich alles bekannt, der braucht sich nicht beklagen) sondern eine vom Linker, der dann die Funktion nicht findet. Die Ursache war ja auch viel weiter oben bereits ausführlich beschrieben worden. Insofern gibt es gar nichts Neues zu mutmaßen.
Sven Woehlbier wrote: > Also ich habe es jedenfalls so gelernt wie ich es geschrieben habe. > Allerdings habe ich vor 1999 Studiert. Hat sich da was mit den Standards > C98 und/oder C99 geändert? In der Hinsicht nicht. Das extern wird nur bei Variablen benötigt, weil man da zwischen Deklaration und Definition unterscheiden muss (und das rein von der Syntax her nicht möglich ist). Funktionsprototypen kann man angeben, soviele man will, aber eine Variable darf nur einmal im gesamten Programm definiert werden, und deshalb muss bei einer zusätzlichen Deklaration dem Compiler mitgeteilt werden, dass es sich um eine solche handelt und er keinen Speicherplatz für die Variable anfordern soll. Ein Funktionsprototyp ist aber immer direkt (auch ohne extern ) als solcher (also als Deklaration) erkennbar. Du kannst das extern da zwar gerne hinschreiben, nur macht es bei Funktionsprototypen keinen Sinn.
@ Jörg Wunsch: siehe in meiner ersten Antwort: "Das interessiert nicht den Compiler sondern den Linker." Aber OK, hinsichtlich der Groß- und Kleinschreibung habe ich den Thread zu unaufmerksam gelesen. Tschau Sven!
@ Johannes M.: Vielen Dank, für die Wissensauffrischung :-)! Tschau Sven!
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.