Forum: Mikrocontroller und Digitale Elektronik Eigener Datentyp (Struct) in Headerdatei unbekannt.


von Mark M. (mom-jovi)


Lesenswert?

Ich habe folgendes Problem mit zwei Modulen in C:

In einer Headerdatei abc.h wird ein struct definiert:
1
struct { /* ... */ } structABC;

In einer weiteren Headerdatei xyz.h steht ein Prototyp, der diesen 
Datentyp in seiner Paramterliste hat:
1
void function(structABC* abc);

Nun meckert der Compiler, dass der Datentyp structABC in xyz.h 
unbekannt ist.
Ich habe nun per include abc.h in xyz.h eingebunden. Das funktioniert 
auch. Aber sowas macht man doch üblicherweise nicht, oder? Wie geht denn 
hier die schöne Lösung? :-)

von Karl H. (kbuchegg)


Lesenswert?

Mark M. schrieb:

> Ich habe nun per include abc.h in xyz.h eingebunden. Das funktioniert
> auch. Aber sowas macht man doch üblicherweise nicht, oder?

Doch. Genau so macht man das.

Du gehst jedes File (egal ob Header-File oder C-Source Code) für sich 
alleine von oben nach unten durch und siehst nach was davon 
C-Schlüsselwörter sind und was du selbst definiert hast. Und dann hältst 
du dich an die Regel: Verwendet werden kann nur, was vorher deklariert 
wurde.

Wenn du also etwas verwenden willst (bei dir der Name einer Struktur in 
einer Parameterliste), dann muss die Sturktur vorher deklariert worden 
sein.

Wenn diese Struktur in einem anderen Header File ist, dann bedeutet das 
dann eben, dass dieses Header File vor der verwendenden Stelle zu 
inkludieren ist.

von Klaus W. (mfgkw)


Lesenswert?

Natürlich macht man das so.
Wenn etwas in einer Headerdatei deklariert ist, und man braucht es in 
einer anderen (.c oder .h), dann wird es dort per #include eingebunden.

Was sonst?
Und warum sollte man das nicht tun?

(Wenn das böse sein sollte, mache ich seit Jahrzehnten Murks. Das willst 
du mir hoffentlich nicht unterstellen????)

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler schrieb:

> (Wenn das böse sein sollte, mache ich seit Jahrzehnten Murks.

:-)
Ich würde sagen, du befindest dich in guter Gesellschaft von ca mehr als 
5 Millionen anderer C-Programmierer.


(OK. eine Alternative gibt es noch in dem Fall. Forward Defintionen. 
Aber die haben dann auch wieder ihre eigenen Probleme)

von Zweifler (Gast)


Lesenswert?

Mark M. schrieb:
> In einer Headerdatei abc.h wird ein struct definiert:struct { /* ... */ } 
structABC;
> In einer weiteren Headerdatei xyz.h steht ein Prototyp, der diesen
> Datentyp in seiner Paramterliste hat:void function(structABC* abc);

Karl Heinz Buchegger schrieb:
> Doch. Genau so macht man das.

Ääähhmmmmm, im Header wird eine Variable definiert. Im C file wird ein 
Datentyp verwendet.

Meine Variante
1
typedef struct structABC { /* ... */ };
2
3
...
4
5
void function(structABC* abc);

von Klaus W. (mfgkw)


Lesenswert?

Wohl wahr!
Das hatte ich auch übersehen.
Die Typdefinition gehört in den Header, die Variable davon nicht.

An deiner Lösung zweifle ich allerdings auch leicht :-)

Besser:
1
typedef struct { /* ... */ } structABC;
2
3
...
4
5
void function(structABC* abc);

von Mark M. (mom-jovi)


Lesenswert?

Zweifler schrieb:
> Ääähhmmmmm, im Header wird eine Variable definiert. Im C file wird ein
> Datentyp verwendet.
Klaus Wachtler schrieb:
> Wohl wahr!
> Das hatte ich auch übersehen.
Zweifler schrieb:
> Meine Variante
1
typedef struct { /* ... */ } structABC;
2
...
3
void function(structABC* abc);

Das geht aber eben nicht, weil structABC aus einem anderen Modul stammt 
und da auch hingehört. void function(structABC* abc); steht dagegen in 
xyz.h als Prototyp einer Funktion in xyz.c !

Klaus Wachtler schrieb:
> Die Typdefinition gehört in den Header, die Variable davon nicht.

Das ist mir auch klar, deswegen hab ich das Thema eröffnet. xyz.c kennt 
structABC, weil ich dort abc.h eingebunden hab. Aber xyz.h weiß nichts 
davon, erst, wenn ich dort nochmal abc.h einbinde.

von Zweifler (Gast)


Lesenswert?

Mark M. schrieb:
> weil structABC aus einem anderen Modul stammt

Das ist keine Variable, sondern mit typedef ein neuer Datentyp. Und 
der gehört natürlich in einen Header, der überall wo dieser Strukturtyp 
benötigt wird, einzubinden ist.

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.