Globale Variable in Funktion nicht erkannt?!

Gast #363288
Lesenswert?

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?!
Gast #363292
Lesenswert?

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 ;-)
Angehängte Dateien:
Persönliche Seite #363293
Lesenswert?

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.
Persönliche Seite #363297
Lesenswert?

@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.
Persönliche Seite #363299
Lesenswert?

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?
Moderator Persönliche Seite #363305
Lesenswert?

> 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.
Gast #363306
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren