Ich habe in meiner main.c ganz zu beginn eine variable definiert (also global). char tmp_var[8]; Nun schreit der Compiler, wenn eine andere Funktion mit diesen Werten arbeiten will: error: `tmp_var' undeclared (first use in this function) Wenn ich in der Funktion die variable nochmal definiere, gleich wie zu Beginn, dann passts ihm. Meine Frage ist warum? Wenn in der erten Zeile des main programmes die Variable definiert wird, warum ist die dann in einer anderen Funktion undeklariert?!
Hi! Wenn ich mich nicht irre, musst du das Array als volatile definieren: volatile char tmp_var[8]; Viel Erfolg, Jürgen Fitschen
Hi, Poste mal ein wenig Code, damit man dir helfen kann. So ist das ein wenig dürftig. Gruß Michael
Habe das WinAVR Project im Anhang. Das Programm sollte jede Sekunde den aktuellen ADC Wert per UART verschicken..... die drm3310 display dateien könnt ihr im Moment vergessen, komemn erst später hinzu... Wie gesagt, wenn ich in der Funktion adc_ergebnis() nicht nochmal die zwei variablen buf_quo[8] und buf_rem[8] definiere, gibt das kompilieren einen error.... Aber seht selbst ;-)
Die globalen Variablen dürfen nicht als "static" deklariert/definiert werden - sonst sind sie nämlich eben NICHT global. Sie dürfen nur in einem Sourcefile definiert werden, damit aber Funktionen aus anderen Sourcefiles auf sie zugreifen können, muss für diese anderen Sourcefiles die Deklaration der Variablen bekannt gemacht werden. Das geschieht mit einer "extern"-Deklaration in einer Headerdatei. In jedem Sourcefile, in dem auf diese globalen Variablen zugegriffen werden soll, muss die Headerdatei mit der Deklaration eingebunden werden. Beispiel: // headerdatei "main.h" extern char buf_quo[8]; // Deklaration // main.c char buf_quo[8]; // Definition. Initialisierung // muss hier erfolgen, wenn benötigt // blafusel.c #include "main.h" // liest Deklaration So eine "extern"-Deklaration teilt dem Compiler analog zum Funktionsprototypen mit, daß es eine Variable des betreffenden Namens und Typs gibt, so daß der Compiler das betreffende Quellfile ohne Fehlermeldung übersetzen kann. Es empfiehlt sich, globale Variablen (wenn man sie denn unbedingt benutzen muss) in eine eigene Quelltextdatei zu packen, und eine Headerdatei gleichen Namens anzulegen, in der die Variablen deklariert werden. Naheliegend ist hier "globals.c/globals.h", da weiß man, was man hat. Als "volatile" müssen Variablen nur dann deklariert werden, wenn sie am Optimizer des Compilers vorbei geändert werden können, was in Interruptroutinen etc. geschehen kann, das aber hat nichts mit dem hier vorliegenden Problem zu tun.
Ach so ist das! Jetzt kapier ich endlich, wie das ist mit dem "extern" Danke für das super Beispiel!Leuchtet mir jetzt ein! ;-)
Probier mal extern char buf_quo[8]; in adc.c oder mach eine gemeinsame .h Datei wo char buf_quo[8] drinsteht.
@Thomas: Genau andersrum. In die Headerdatei gehört die Deklaration, nicht die Definition der Variablen. Wenn man die Definition der Variablen in die Headerdatei packt, dann wird für jedes einzelne Sourcefile im Projekt, das diese Headerdatei einbindet, eine neue globale Variable angelegt ... was dann vollkommen zu recht der Linker moniert. gcc bietet eine Option, dies zuzulassen und die Kopien quasi aufeinander abzubilden, das aber ist nicht standardkonform und meiner Ansicht nach übler Murks.
Ja, du hast wohl recht. Obwohl ich dieses "Kopieren" der globalen Variable nicht entdecken kann. Allerdings wäre das "extern char buf_quo[8];" in adc.c doch trotzdem richtig wenn in main.c "char buf_quo[8];" steht.
Das "kopieren" geschieht, wenn folgendes char globale_variable; in einer Headerdatei steht, die in mehrern Sourcefiles eines Projektes eingebunden wird. Das hast Du so vorgeschlagen: oder mach eine gemeinsame .h Datei wo char buf_quo[8] drinsteht. Davon abgesehen ist es natürlich auch möglich, die extern-Deklaration nicht in die Headerdatei, sondern in jedes Sourcefile zu schreiben, in dem man sie benötigt. Muss ich wirklich darauf hinweisen, daß so eine Vorgehensweise ausgemachter Murks ist?
Ich habe doch gesagt, dass du recht hast. Allerdings merke ich nichts von diesem "Kopier"-Effekt. Hab es gerade getestet (Im Endeffekt ist das nochmal mein Posting von vorhin).
Wenn Du den "Kopier"-Effekt nicht feststellen kannst (also Dein Linker nicht über mehrfach definierte Symbole klagt), dann verwendest Du gcc in eben jenem nicht standardkonformen Modus, der klaglos Symbol-Doubletten zusammenfasst. Ich vermag Dir aber nicht zu sagen, wie exakt die dafür verantwortliche Kommandozeilenoption lautet; tut mir leid.
Also ich seh da jetzt nichts besonderes dran: gcc -ansi -pedantic -Wall -g main.c func.c -o main aber egal
Achso, es ist umgekehrt. Man braucht diesen Parameter damit er den Fehler anzeigt. Sehr interessant. Wieder was gelernt :)
> Man braucht diesen Parameter damit er den > Fehler anzeigt. Ja, der default von GCC ist, .bss-Variablen (nicht initialisierte globale Variablen) in sogenannte Common-Blöcken anzulegen. Dieses Linker-Feature stammt von FORTRAN und gestattete es dort, Datenbereiche aus verschiedenen Moduln im Linker überlagern zu lassen. Ich vermute mal, dass das Ur-C von K&R das Wort "extern" einfach noch nicht besass. Dadurch sahen die Deklaration und die Definition einer nicht initialisierten Variablen identisch aus. Durch die Benutzung eines Common-Bereichs wurden dann alle gleichnamigen globalen Variablen durch den Linker auf einen einzigen Speicherbereich abgebildet. Später blieb die daraus resultierende Schlampigkeit, Deklarationen und Defininitionen nicht sauber zu trennen, in der Unix-Welt dann noch lange erhalten (weil das einfach in alten Quelltexten usus war), sodass die Compiler das nach wie vor so implementieren.
Hallo komisch, dass bei dem Compiler, den ich hier verwende (CAVR) und auch in diversen Büchern steht (in dem Ansi C erklärt wird) , dass -static- sehr wohl auch global sein kann - vorausgesetzt es -nicht!- in einer Funktion deklariert wird und es sich nur auf diese Datei bezieht, in der es steht. Darüber hinaus werden mit static deklarierierte Variablen immer mit 0, vom Compiler initialisiert und von dem irgendwie auch speziell optimiert. Extern hingegen sollte sich, soweit ich weiß, eben noch "mehr" global, für mehrere Dateien sein, die auf dieselbe Variable zugreifen. Nun zum Problem: (was bei CAVR genauso auftritt) Variablen die ohne diese Parameter deklariert sind, müssen auf jeden Fall -vor den Funktionen stehen, die sie verwenden und das geschieht normal am Datei Anfang. mfg Ulli
@Jörg Wunsch: Sehr interessant. Danke! @Ulli: Ich glaub die Worte die du suchst sind "File Scope" bzw. "Gobal Scope":)
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.