struct in Kombination mit typedef

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
starcow
Establishment
Beiträge: 527
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

struct in Kombination mit typedef

Beitrag von starcow »

Tach zusammen! :-)

Wenn ich ein struct im Zuge eines typedefs deklariere, dann habe ich ja im Wesentlichen "kombinatorisch" drei Möglichkeiten.

Code: Alles auswählen

typedef struct         { ... } name_t; // Das struct selbst ist anonym
typedef struct name_t  { ... } name_t; // Der struct "Identyfier" wird durch das typedef verdeckt
typedef struct name    { ... } name_t; // Es existieren zwei "Identyfier"
Wo liegen hier die Vorteile (Nachteile?) der verschiedenen Methoden?
In der WindowsAPI begegne ich durchgängig der dritten Methode.

Code: Alles auswählen

typedef struct tagNAME { ... } NAME, *PNAME;
Wie beurteilt ihr eigentlich die Konvention, dem per typedef definierten Typ das Postfix _t anzuhängen (Beispiel uint32_t)?
Sinnvolle Regel oder unnötiger Firlefanz? :-)

Gruss, starcow
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Alexander Kornrumpf
Moderator
Beiträge: 2113
Registriert: 25.02.2009, 13:37

Re: struct in Kombination mit typedef

Beitrag von Alexander Kornrumpf »

Vielleicht solltest du dazu sagen, ob du versuchst C oder C++ zu schreiben, denn in C++ brauchst du das typedef gar nicht, soweit ich mich erinnere.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4857
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: struct in Kombination mit typedef

Beitrag von Schrompf »

Ich kenne immer nur typedef _some_struct_t { ... } some_struct_t;, also Variante 3. Dass die gleich heißen dürfen, wusste ich nicht. Man macht das aber wirklich nur, weil man in C sonst immer struct SomeStruct obj; schreiben müsste, und das typedef erspart einem das struct vornedran. In C++ braucht es das nicht mehr, da typedeft beziehungsweise usingt man wirklich nur noch, wenn man ein Alias haben will.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: struct in Kombination mit typedef

Beitrag von Krishty »

In meinem C-Code benutze ich gar nichts davon, sondern schreibe explizit struct Foo hin, wann immer ich es brauche. In C++ lohnt es zwar, den Typ einer Variable wegzuabstrahieren und nur die Semantik abzubilden (auto everywhere!), aber das geht eben nur in C++ – weil nur C++ erlaubt, eigene Typen zu schreiben, die sich wie ein int oder ein Zeiger oder sonstwas verhalten, unabhängig davon, ob sie nun als class oder enum class oder sonstwas implementiert sind.

In C geht das nicht. Du kannst in C keine Smart-Pointer-Klasse haben, weil ein struct immer komplett anders zu benutzen sein wird als ein int *. Es gibt ja keine überladenen Operatoren. COM & Co. versuchen das via Makro, aber dann sieht dein Code eh ganz anders aus.

Deshalb sehe ich nicht recht ein, das struct wegzu… aliasen? Das nennt man Alias, oder?

Anyway. Davon ab ist die Endung _t in POSIX reserviert. So lange du nur auf Windows kompilierst, kann dir das egal sein. Falls du mal auf Linux oder einem anderen POSIX-System kompilieren möchtest, ist das nicht mehr zukunftssicher, weil irgendwann ein Header einen eigenen Typ mit dem selben Namen einführen könnte. Nix Schlimmes, just saying.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
starcow
Establishment
Beiträge: 527
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: struct in Kombination mit typedef

Beitrag von starcow »

Alexander Kornrumpf hat geschrieben: 16.09.2023, 18:15 Vielleicht solltest du dazu sagen, ob du versuchst C oder C++ zu schreiben, denn in C++ brauchst du das typedef gar nicht, soweit ich mich erinnere.
Stimmt, entschuldigt das Versäumnis! :-)
Ich dachte hier tatsächlich an plain C.
Schrompf hat geschrieben: 16.09.2023, 22:17 Dass die gleich heißen dürfen, wusste ich nicht.
Guter Punkt. Also ehrlich gesagt fehlt mir jetzt auch eine valide Referenz dafür, dass man das so machen darf. Weder clang noch gcc geben mir in diesem Zusammenhang eine Warnung aus - was ja aber eigentlich noch kein Garant dafür ist, dass dies auch tatsächlich erlaubt wäre. Hmmm...
Krishty hat geschrieben: 16.09.2023, 22:28 In meinem C-Code benutze ich gar nichts davon, sondern schreibe explizit struct Foo hin, wann immer ich es brauche. In C++ lohnt es zwar, den Typ einer Variable wegzuabstrahieren und nur die Semantik abzubilden (auto everywhere!), aber das geht eben nur in C++ – weil nur C++ erlaubt, eigene Typen zu schreiben, die sich wie ein int oder ein Zeiger oder sonstwas verhalten, unabhängig davon, ob sie nun als class oder enum class oder sonstwas implementiert sind.
In C geht das nicht. Du kannst in C keine Smart-Pointer-Klasse haben, weil ein struct immer komplett anders zu benutzen sein wird als ein int *. Es gibt ja keine überladenen Operatoren. COM & Co. versuchen das via Makro, aber dann sieht dein Code eh ganz anders aus.

Deshalb sehe ich nicht recht ein, das struct wegzu… aliasen? Das nennt man Alias, oder?
Warte.
Ich dachte eigentlich genau das tut typedef. Damit etabliere ich doch einen neuen Typ? Hast du eine Situation im Kopf, die den Unterschied deutlich macht? So ganz kann ich dir noch nicht folgen.
Soweit ich sehe, wird typedef oft genutzt, einfach um weniger tippen zu müssen (struct fällt weg). Jedoch habe ich auch schon aufgeschnappt, dass das aus einem bestimmten Grund (der mir nicht klar ist) potentiell ungünstig sein kann.
Was sind deine Gründe, darauf zu verzichten?
Davon ab ist die Endung _t in POSIX reserviert. So lange du nur auf Windows kompilierst, kann dir das egal sein. Falls du mal auf Linux oder einem anderen POSIX-System kompilieren möchtest, ist das nicht mehr zukunftssicher, weil irgendwann ein Header einen eigenen Typ mit dem selben Namen einführen könnte. Nix Schlimmes, just saying.
Oh! Sehr guter Hinweis, danke!
kein _t anhängen, weil potentiell reserviert!
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: struct in Kombination mit typedef

Beitrag von dot »

starcow hat geschrieben: 19.09.2023, 13:28
Schrompf hat geschrieben: 16.09.2023, 22:17 Dass die gleich heißen dürfen, wusste ich nicht.
Guter Punkt. Also ehrlich gesagt fehlt mir jetzt auch eine valide Referenz dafür, dass man das so machen darf. Weder clang noch gcc geben mir in diesem Zusammenhang eine Warnung aus - was ja aber eigentlich noch kein Garant dafür ist, dass dies auch tatsächlich erlaubt wäre. Hmmm...
In C dürfen sie das. Grund ist, dass die Namen von structs und enums in C sogenannte Tags sind die effektiv einen eigenen separaten Namespace haben. typedef Names dagegen sind ordinary identifiers.
starcow hat geschrieben: 19.09.2023, 13:28
Krishty hat geschrieben: 16.09.2023, 22:28 In meinem C-Code benutze ich gar nichts davon, sondern schreibe explizit struct Foo hin, wann immer ich es brauche. In C++ lohnt es zwar, den Typ einer Variable wegzuabstrahieren und nur die Semantik abzubilden (auto everywhere!), aber das geht eben nur in C++ – weil nur C++ erlaubt, eigene Typen zu schreiben, die sich wie ein int oder ein Zeiger oder sonstwas verhalten, unabhängig davon, ob sie nun als class oder enum class oder sonstwas implementiert sind.
In C geht das nicht. Du kannst in C keine Smart-Pointer-Klasse haben, weil ein struct immer komplett anders zu benutzen sein wird als ein int *. Es gibt ja keine überladenen Operatoren. COM & Co. versuchen das via Makro, aber dann sieht dein Code eh ganz anders aus.

Deshalb sehe ich nicht recht ein, das struct wegzu… aliasen? Das nennt man Alias, oder?
Warte.
Ich dachte eigentlich genau das tut typedef. Damit etabliere ich doch einen neuen Typ? Hast du eine Situation im Kopf, die den Unterschied deutlich macht? So ganz kann ich dir noch nicht folgen.
Soweit ich sehe, wird typedef oft genutzt, einfach um weniger tippen zu müssen (struct fällt weg). Jedoch habe ich auch schon aufgeschnappt, dass das aus einem bestimmten Grund (der mir nicht klar ist) potentiell ungünstig sein kann.
Was sind deine Gründe, darauf zu verzichten?
typedef macht keinen neuen Typ sondern führt einen Alias für einen bestehenden Typ ein:

Code: Alles auswählen

typedef int bla;
bla hier ist kein separater Typ, sondern nur ein Alias für den Typ int. In C merkt man den Unterschied kaum, in C++ merkt man ihn sofort:

Code: Alles auswählen

void fun(int) {}
void fun(bla) {}  // ERROR, fun already defined
Benutzeravatar
starcow
Establishment
Beiträge: 527
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: struct in Kombination mit typedef

Beitrag von starcow »

Danke dot, sehr gut erklärt!

Könnte man nicht einfach dazu übergehen, ganz grundsätzlich anonyme structs in Kombination mit typedef zu verwenden (quasi als Standard)?

Code: Alles auswählen

typedef struct { ... } Name; // Das struct selbst ist anonym
Das ginge ja eigentlich einzig nur dann nicht, wenn ich innerhalb dieses structs noch einen Pointer des selben struct Typs benötige (z.B. bei einer Linked List).
Oder übersehe ich da vielleicht etwas?
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: struct in Kombination mit typedef

Beitrag von dot »

starcow hat geschrieben: 23.09.2023, 16:51 Könnte man nicht einfach dazu übergehen, ganz grundsätzlich anonyme structs in Kombination mit typedef zu verwenden (quasi als Standard)?
Naja, wie du selber schon angemerkt hast geht das halt nicht wenn dein struct Pointer auf sich selbst beinhalten soll. Abgesehen von einem solchen Fall kann man einfach typedef auf unnamed struct machen. Ist halt eine Frage der Konsistenz…
Antworten