Forum: Mikrocontroller und Digitale Elektronik Struct globalisieren?


von I. L. (Gast)


Angehängte Dateien:

Lesenswert?

Moin,

offensichtlich bin ich zu blöd ein
1
 struct
zu globalisieren? Was mache ich denn da falsch?


Bekomme immer die Fehlermeldung:
../Funktionen.c:15: error: invalid use of undefined type 'struct 
Werte_t'

Ich hab das Ding doch definiert!

Gruß Knut

von Karl H. (kbuchegg)


Lesenswert?

Sieh dir nur dein File funktionen.c an
1
// Funktionen.c
2
3
#include "main.h"
4
#include "Funktionen.h"
5
6
7
8
void XYZ (void);
9
10
11
void xyz (void)
12
{
13
  Werte.Var1 = 10;
14
15
}

Jetzt lösen wir mal die #include auf, sprich wir machen genau das 
gleiche was auch der Präprozessor macht.
Dann steht da:
1
// main.h
2
3
4
5
#include <stdio.h>
6
#include <avr/io.h>
7
#include <util/delay.h>
8
9
10
11
12
13
extern volatile struct Werte_t Werte;
14
15
16
// Funtkionen.h
17
18
extern void XYZ (void);
19
20
21
22
void XYZ (void);
23
24
25
void xyz (void)
26
{
27
  Werte.Var1 = 10;
28
29
}

und das wird jetzt compiliert. Siehst du da irgendwo eine Definition wie 
denn nun ein struct Werte_t aussieht? Also ich nicht.


*.c Files werden unabhängig voneinander compiliert!
Das du in main.c die Defintion dieser struct hast, ist zwar nett, 
interessiert aber den Cmopiler nicht, wenn er funktionen.c compiliert.

Zieh die Struktur in ein Header File, so dass alle *.c Files, die die 
Struktur benötigen sie zur Verfügung haben.

main.h
******
1
// main.h
2
3
#include <stdio.h>
4
#include <avr/io.h>
5
#include <util/delay.h>
6
7
struct Werte_t
8
{
9
  uint16_t var1;
10
  uint16_t var2;
11
};
12
13
extern volatile struct Werte_t Werte;

main.c
******
1
#include "main.h"
2
3
4
volatile struct Werte_t Werte;
5
6
int main (void)
7
{
8
  while(1);
9
  return (0);
10
}


Machen wir jetzt das gleiche Spielchen wieder und sehen uns an, was der 
Präprozessor auf funktionen.c macht, dann kommt da raus
1
// main.h
2
3
#include <stdio.h>
4
#include <avr/io.h>
5
#include <util/delay.h>
6
7
struct Werte_t
8
{
9
  uint16_t var1;
10
  uint16_t var2;
11
};
12
13
extern volatile struct Werte_t Werte;
14
15
// Funtkionen.h
16
17
extern void XYZ (void);
18
19
20
21
void XYZ (void);
22
23
24
void xyz (void)
25
{
26
  Werte.Var1 = 10;
27
28
}

E voila!
Jetzt ist auch in Funktionen.c bekannt, wie eine struct Werte_t 
aussieht.

von klops (Gast)


Lesenswert?

Compiler muss Deine Def natürlich auch sehen.
Die ist aber nur im main.c sichtbar,
nicht in Funktionen.c
Abhilfe: Nach main.h verschieben

von I. L. (Gast)


Lesenswert?

Ich dachte mit
1
extern volatile struct Werte_t Werte;

würde ich dem Compiler sagen, dass die
1
 struct
 woanders definiert ist grübel.


Soll dann:
1
volatile struct Werte_t
2
{
3
  uint16_t var1;
4
  uint16_t var2;
5
6
} Werte;

in die main.h? Dann lege ich doch aber in jedem *.c -File wo ich die 
Main.h includiere ein struct an, oder nicht?



Gruß Knut

von Karl H. (kbuchegg)


Lesenswert?

Ingo L. schrieb:
> Ich dachte mit
>
1
> extern volatile struct Werte_t Werte;
2
>
>
> würde ich dem Compiler sagen, dass die
1
 struct
 woanders
> definiert ist grübel.

Und wie soll der Compiler die finden?
Damit er mittels

  Werte.Var1 = 10;

darauf zugreifen kann, muss er wissen wie die Struktur aussieht! Nur 
woher weiß er denn das, wenn du es ihm nicht mitteilst.
Der COmpiler durchsucht nicht eigenständig alle deine *.c Files auf der 
Platte auf der Suche nach einer entsprechenden Strukturbeschreibung!

Er hat einen Eingangstext und das ist das *.c File, welches du ihm 
gibst.
Da (nachdem alle #include aufgelöst sind) muss alles enthalten sein!

von Karl H. (kbuchegg)


Lesenswert?

Ingo L. schrieb:

> in die main.h?

Siehe
Beitrag "Re: Struct globalisieren?"

(Ich hab noch ergänzt)

> Dann lege ich doch aber in jedem *.c -File wo ich die
> Main.h includiere ein struct an, oder nicht?

Macht doch nichts

1) stimmen alle Strukturbeschreibungen derselben Struktur in einem
   Programm auf die Art automatisch überein

2) Ist das ja nur die Blaupause. Quasi der Plan wie eine derartige
   Variable aussehen würde, wenn man eine anlegen würde.
   Deswegen wird dein Programm ja nicht größer.

von Karl H. (kbuchegg)


Lesenswert?

Dazu kommt noch die Unsitte mittels
1
volatile struct Werte_t
2
{
3
  uint16_t var1;
4
  uint16_t var2;
5
6
} Werte;

gleichzeitig
* zu definieren wie eine Struktur aussieht
* und auch noch in einem Aufwasch eine entsprechende Variable
  davon zu definieren

Nimm Abstand davon, wenn dich das verwirrt und trenne die Dinge!
1
struct Werte_t
2
{
3
  uint16_t var1;
4
  uint16_t var2;
5
6
};
7
8
volatile struct Werte_t Werte;

Nur die Definition wie eine Struktur aussieht, kommt ins Header File.
Die Definition der Variablen bleibt nach wie vor in main.c!

von I. L. (Gast)


Lesenswert?

Ok, danke. Sorry wenn ich jetzt nochmal äußerst dumm frage, ich will es 
nur endgültig verstanden haben:


Wenn ich:
1
struct Werte_t
2
{
3
  uint16_t var1;
4
  uint16_t var2;
5
};
6
7
extern volatile struct Werte_t Werte;
in meinen Header schreibe, wird nicht dieses Struct erzeugt, sondern nur 
wie es aussieht?!

Mit dem
1
extern volatile struct Werte_t Werte;
sage ich dem Compiler, dass das Struct woanders definiert ist?!

Und wenn wenn ich dann in meiner main.c
1
volatile struct Werte_t Werte;
schreibe wird erst HIER ein Struct mit den Membern var1, var2 
angelegt!?

Wenn ich das:
1
volatile struct Werte_t Werte;
in einer anderen *.c schreibe, was passiert dann? Wird das Struct 
doppelt erzeugt? Offensichtich nicht, denn der Programmspeicher bleibt 
weiterhin 4Byte.


Gruß Knut

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Wenn ich:
(...)
> in meinen Header schreibe, wird nicht dieses Struct erzeugt, sondern nur
> wie es aussieht?!

Exakt.

> Mit dem
>
1
> extern volatile struct Werte_t Werte;
2
>
> sage ich dem Compiler, dass das Struct woanders definiert ist?!

Genau.

> Und wenn wenn ich dann in meiner main.c
>
1
> volatile struct Werte_t Werte;
2
>
> schreibe wird erst HIER ein Struct mit den Membern var1, var2
> angelegt!?

So isses.

> Wenn ich das:
>
1
> volatile struct Werte_t Werte;
2
>
> in einer anderen *.c schreibe, was passiert dann? Wird das Struct
> doppelt erzeugt?

Ja.

> Offensichtich nicht, denn der Programmspeicher bleibt
> weiterhin 4Byte.

Es gibt ärgerlicherweise eine Konfigurationsoption des gcc, 
solchermaßen identisch definierte Variablen zusammenzulegen.

Damit wird dieser Programmierfehler verborgen, andere Compiler 
(genauer: Linker) geben da eine Fehlermeldung aus.

von I. L. (Gast)


Lesenswert?

OK, vielen dank. Ich habs begriffen!!!

Schönen Abend noch



Gruß Knut

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.