mikrocontroller.net

Forum: Compiler & IDEs Include funktioniert nicht


Autor: loki81 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: loki81 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas Watterott (andreasw) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Obacht bei der Groß- und Kleinschreibung bei den Dateinamen.

Autor: loki81 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Sven Woehlbier (woehlb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ loki81:

Es gibt in TIMEB.C und MAIN.C ein include von TIMEB.H.

TIMEB.H:
extern int i;
void timeb_init(void) /*für TIMEB.C OK*/

Für MAIN.C müßte es aber folgendermaßen aussehen:
extern void timeb_init(void);

Tschau Sven!

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sven Woehlbier wrote:

> Für MAIN.C müßte es aber folgendermaßen aussehen:
>
>
> extern void timeb_init(void);
> 

Falsch.  Es muss gar nicht.
void timeb_init(void);

tut exakt dasselbe, oder was sollte daran aus Sicht des Compilers
anders funktionieren?

Autor: Sven Woehlbier (woehlb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Jörg Wunsch:

Das interessiert nicht den Compiler sondern den Linker.

in MAIN.C steht durch include <timeb.h>
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!

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sven Woehlbier (woehlb)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sven Woehlbier (woehlb)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Sven Woehlbier (woehlb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Johannes M.:

Vielen Dank, für die Wissensauffrischung :-)!

Tschau Sven!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.