Hallo,
ich muß euch mal mit static auf die Nerven gehen.
Es gibt zwar schon genug Threads dazu, aber mir ist da noch nicht ganz
was schlüssig.
Problem:
Ich habe eine Headerdatei in der ich eine globale Variable als uint8_t
deklariere. Diese Headerdatei binde ich in alle C Dateien die diese
globale Variable benötigen ein.
Beispiel:
1
//Globale_Header.h
2
uint8_tModus;//Variable soll Global genutzt werden
3
4
5
//C_Datei1.c
6
include"Globale_Header.h"
7
8
voidTest1(void)
9
{
10
Modus=1
11
}
12
13
//C_Datei2.c
14
include"Globale_Header.h"
15
voidTest2(void)
16
{
17
...
18
//hier folgt eine Ausgabe der "Modus" Variable über Uart
19
...
20
}
Die Variable "Modus" ist in der C_Datei2.c nicht 1!
Wenn ich ein static in der Headerdatei vor der Variable Modus setze,
funktioniert das zwar (dann ist Modus in der C_Datei2.c auch 1), ich
bekomme aber eine Compilerwarnung "Modus defined but not used".
Wie macht man das richtig?
Gruß Antong
Anton G. schrieb:> Wie macht man das richtig?
mit "extern"
und dazu muss die Variabel auch noch in einer C datei angelegt werden.
In der Header datei steht dann nur drin das die Variable existiet.
nun ja Variablen definiert man nicht in Headerdateien sondern
deklariert Sie dort. Falls du also eine Variable in allen
Files brauchst:
1
//Globale_Header.h
2
extern uint8_t Modus; //Variable soll Global genutzt werden
3
4
//C_Datei1.c
5
include "Globale_Header.h"
6
7
uint8_t Modus; //Variable wird nur einmal definiert
8
9
void Test1(void)
10
{
11
Modus = 1
12
}
13
14
//C_Datei2.c
15
include "Globale_Header.h"
16
void Test2(void)
17
{
18
...
19
//hier folgt eine Ausgabe der "Modus" Variable über Uart
20
...
21
}
so wie du das machst erzeugst du 2 Variablen in unterschiedliche
Files mit dem gleichen Namen das dürfte ohne Fehlermelung gar nicht
funktionieren
Thomas
Code schrieb:> Mach es lieber mit static Deklaration, sowie Get und Set Routinen.
dafür muss man aber auch die Variable in einer C datei anlegen. Außerdem
ist das ganze noch duch den funtionaufruf sehr langsam.
Wenn ich das nach Thomas (Gast) Variante mache, habe ich immer noch das
Problem, dass scheinbar zwei Variablen genutzt werden.
In C_Datei2.c ist Modus immer noch nicht 1.
Muß ich die dann noch static machen? Habe ich versucht. Ich habe in der
Header und in der C Datei ein static davor geschrieben.
Bekomme dann aber die Compiler Meldung "multiple storage classes in
declaration specifiers" und "static declaration of Modus follows non
static declaration".
Anton G. schrieb:> Wenn ich das nach Thomas (Gast) Variante mache, habe ich immer noch das> Problem, dass scheinbar zwei Variablen genutzt werden.
nein, so ist es richtig und da gibt es nicht 2 Variablen.
Wen es nur einmal die zeile (in einer C datei)
uint8_t Modus;
gibt, dann ist die Variable auch nur einmal da. Wenn ein extern davor
steht, dann wird sie nicht angelegt.
Peter II schrieb:> Außerdem> ist das ganze noch duch den funtionaufruf sehr langsam.
Das würde pauschal nicht unterschreiben. Wenn man den Optimierer
vewendet, wird das i.d.R. "geinlined". Das muss natürlich die Toolchain
unterstützen.
Coder schrieb:> Das würde pauschal nicht unterschreiben. Wenn man den Optimierer> vewendet, wird das i.d.R. "geinlined". Das muss natürlich die Toolchain> unterstützen.
er kann es aber nicht geinlined, weil die Set und Get funktionen ja in
einer Extra C datei stehen müssen, sonst kann man nicht auf die Static
variable zugreifen. Und wenn die Variabel als extern definiert ist, kann
man auch die Set und Get sachen weglassen.
Coder schrieb:> Peter II schrieb:>> Außerdem>> ist das ganze noch duch den funtionaufruf sehr langsam.>> Das würde pauschal nicht unterschreiben. Wenn man den Optimierer> vewendet, wird das i.d.R. "geinlined". Das muss natürlich die Toolchain> unterstützen.
Und die Funktion muß im Header definiert und inline sein.
Anton G. schrieb:> Wenn ich das nach Thomas (Gast) Variante mache, habe ich immer noch das> Problem, dass scheinbar zwei Variablen genutzt werden.
Woran erkennst du das denn? Die von ihm angegebene Variante ist korrekt.
Entweder interpretierst du das beobachtete Verhalten falsch, oder der
Fehler steckt in dem Teil des Code, den du verheimlicht hast. Deshalb
ist es auch immer besser, nicht irgendwelchen für's Posting
zusammengetippten Pseudo-Code zu zeigen, sondern ein minimales, aber
vollständiges echtes Programm, das auf dem Prozessor den angegebenen
Fehler hat.
> Muß ich die dann noch static machen?
Nein. Static bewirkt ja genau, daß die Variable dann zweimal vorhanden
ist.
Peter II schrieb:> Anton G. schrieb:>> Wenn ich das nach Thomas (Gast) Variante mache, habe ich immer noch das>> Problem, dass scheinbar zwei Variablen genutzt werden.>> nein, so ist es richtig und da gibt es nicht 2 Variablen.>>> Wen es nur einmal die zeile (in einer C datei)>> uint8_t Modus;>> gibt, dann ist die Variable auch nur einmal da. Wenn ein extern davor> steht, dann wird sie nicht angelegt.
Ich gebe dir recht. Das funktioniert doch. Allerdings nur, wenn ich in
der C Datei "Modus" nicht definiere, sondern initialisiere mit z.B.
"uint8_t Modus = HAND" (Hand ist definiert in der "Globale_Header.h" als
0.
Ich hatte das auch nur definiert und dann direkt in der Main von der
C_Datei1.c mit "Modus = 1" zugewiesen. Das klappt nicht.
Wenn ich aber wie oben geschrieben z.B. erst mal einen Wert mit
initialisiere (kann auch ruhig eine 0 sein), dann funktioniert das
einwandfrei und in der C_Datei2.c ist Modus = 1
Komisch, oder gibt es da eine logische Erklärung.
Vielen Dank erst einmal euch allen.
Peter II schrieb:> Coder schrieb:>> Das würde pauschal nicht unterschreiben. Wenn man den Optimierer>> vewendet, wird das i.d.R. "geinlined". Das muss natürlich die Toolchain>> unterstützen.>> er kann es aber nicht geinlined, weil die Set und Get funktionen ja in> einer Extra C datei stehen müssen, sonst kann man nicht auf die Static> variable zugreifen. Und wenn die Variabel als extern definiert ist, kann> man auch die Set und Get sachen weglassen.
Nicht umsonst schrieb ich, Wenn es die Toolchain unterstützt. TI's Code
Composer Toolchain kann das zum Beispiel; ist natürlich nicht für den
AVR :-).
Anton G. schrieb:> Ich gebe dir recht. Das funktioniert doch. Allerdings nur, wenn ich in> der C Datei "Modus" nicht definiere, sondern initialisiere mit z.B.> "uint8_t Modus = HAND" (Hand ist definiert in der "Globale_Header.h" als> 0.
Das ist genauso eine Definition. Außer daß du die Variable explizit mit
0 initialisierst anstatt implizit, ist da kein Unterschied.
> Ich hatte das auch nur definiert und dann direkt in der Main von der> C_Datei1.c mit "Modus = 1" zugewiesen. Das klappt nicht.> Wenn ich aber wie oben geschrieben z.B. erst mal einen Wert mit> initialisiere (kann auch ruhig eine 0 sein), dann funktioniert das> einwandfrei und in der C_Datei2.c ist Modus = 1>> Komisch, oder gibt es da eine logische Erklärung.
Nein, aber ich habe das Gefühl, daß irgendein wichtiger Teil der
Information fehlt.