Forum: Compiler & IDEs verschachtelte typedef


von Alexander G (Gast)


Lesenswert?

Guten Abend!

Ich bin gerade auf das Problem gestoßen, dass mehrere typedef in ihrer 
Definition aufeinander beruhen und somit immer der erste typedef einen 
Fehler schmeißt, weil er die jeweils andere Definition noch nicht kennt.
1
typedef void (*S_midi_read_performed)(const S_midi_class *);
2
3
typedef struct {
4
  S_midi_packet_decoder decoder;
5
  S_midi_read_performed readPerformed;
6
  S_midi_write_performed writePerformed;
7
} S_midi_callbacks;
8
9
typedef struct {
10
  S_midi_buffer* rxBuffer;
11
  S_midi_buffer* txBuffer[2];
12
  S_midi_callbacks sCallbacks;
13
  unsigned char bTxEndpoint;
14
  unsigned char bRxEndpoint;
15
} S_midi;
16
17
typedef struct {
18
  S_std_class sStdClass;
19
  S_midi sMidi;
20
21
} S_midi_class;

Wie geht man denn da an die Sache ran?
Alexander

von Stefan E. (sternst)


Lesenswert?

> Wie geht man denn da an die Sache ran?

Indem man vor die Typedefs Vorwärtsdeklarationen der Structs packt.
Und dann in den Typdefs nicht die neuen Typen verwenden, sondern die 
Structs selber. Dazu dürfen die natürlich nicht anonym sein.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Alexander G schrieb:

> Wie geht man denn da an die Sache ran?

Mit einem incomplete type:
1
struct s_midi_class;
2
3
typedef void (*S_midi_read_performed)(const struct s_midi_class *);
4
5
...
6
7
typedef struct s_midi_class {
8
  ...
9
} S_midi_class;

Falls das Ganze für C++ ist, kannste die typedefs für die
struct-Typen auch gleich in die Tonne kloppen: struct s_midi_class
definiert den Namen s_midi_class in C++ als Typnamen (innerhalb
des entsprechenden Scopes), anders als bei C, wo der Name nur
innerhalb des struct namespaces definiert wird.

von Alexander G (Gast)


Lesenswert?

Ahh das probiere ich gleich mal aus. Ich nehme mal an eine
> Vorwärtsdeklarationen der Structs
ist also eine struct Definition ohne typedef ja? Hätte ich natürlich 
drauf kommen können. Vielen Dank

@Jörg Wunsch
Das ganze soll C sein und das Wort "Class" in den typen sollen keine C++ 
Klassen oder so sein, sondern auf ein USB Midi-Class Gerät verweisen =)

Danke noch mal

von Stefan E. (sternst)


Lesenswert?

Alexander G schrieb:
> Ahh das probiere ich gleich mal aus. Ich nehme mal an eine
>> Vorwärtsdeklarationen der Structs
> ist also eine struct Definition ohne typedef ja?

Es ist sogar noch weniger. Eine struct ohne Inhalt quasi. ;-)
(das, was Jörg in der ersten Zeile seines Beispiels hat)

von Simon K. (simon) Benutzerseite


Lesenswert?


von Rolf Magnus (Gast)


Lesenswert?

> Ahh das probiere ich gleich mal aus. Ich nehme mal an eine
>> Vorwärtsdeklarationen der Structs
> ist also eine struct Definition ohne typedef ja?

Nö. Der typedef hat damit nix zu tun. Eine Deklaration ist einfach nur 
eine Bekanntmachung des Namens einer Struktur, während eine Definition 
auch deren Inhalt bekannt gibt.
Der typedef gibt ihr nur einen alternativen Namen. Deine obigen 
Definitionen haben namenlose Strukturen definiert, die dann über den 
Typedef einen "alisas"-Namen bekommen haben.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?


von Alexander G (Gast)


Lesenswert?

Gut also jetzt hab ich wirklich begriffen, wie das funktioniert und mein 
Code lässt sich nun compilieren. Ich habe lediglich Jörgs Beispiel 
hinzugefügt und damit ging es dann. Was auch immer ihr sagt was das 
jetzt bewirkt und wie es heißt,
1
struct s_midi_class;
schaut für mich einfach mal wie ein Prototyp aus und das ist genau 
wonach ich gesucht habe.

Vielen Dank für die Hilfe

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Alexander G schrieb:

> schaut für mich einfach mal wie ein Prototyp aus und das ist genau
> wonach ich gesucht habe.

Offiziell heißt es (glaub ich, bin gerade zu faul, es nachzulesen)
"incomplete struct type".  Der Begriff "Vorwärtsdeklaration" stammt
eher aus Pascal, meint aber das gleiche.

Ein Prototyp ist in C ein spezielles Konstrukt, das eine Funktion
mit ihren Parametern deklariert.

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.