Struct globalisieren?

Gast #2023936
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
Angehängte Dateien:
#2023945
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.
Gast #2023956
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
#2023965
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!
#2023974
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.
#2023986
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!
Gast #2024027
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
Persönliche Seite #2024038
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.

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