Forum: Compiler & IDEs Include funktioniert nicht


von loki81 (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von loki81 (Gast)


Angehängte Dateien:

Lesenswert?

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

von Andreas W. (andreasw) Benutzerseite


Angehängte Dateien:

Lesenswert?

Obacht bei der Groß- und Kleinschreibung bei den Dateinamen.

von loki81 (Gast)


Lesenswert?

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

von Stefan E. (sternst)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Stefan E. (sternst)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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...

von Sven W. (woehlb)


Lesenswert?

@ 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!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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?

von Sven W. (woehlb)


Lesenswert?

@  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!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> 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.

von Sven W. (woehlb)


Lesenswert?

@  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!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Johannes M. (johnny-m)


Lesenswert?

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.

von Sven W. (woehlb)


Lesenswert?

@  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!

von Sven W. (woehlb)


Lesenswert?

@  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
Noch kein Account? Hier anmelden.