Ich verstehe allerdings nicht, was mit diesem Design Pattern bezweckt
werden soll.
Kennt sich jemand genug in C++ aus, den Zweck zu erklären?
Viele Grüße
W.T.
Man kann auf diese Weise sowohl in C als auch in C++ mit
"libname_structname_t NAME" eine Strukturvariable definieren. Ohne das
Typedef ginge das nur in C++ und in C müsste man noch "struct"
davorsetzen, weil Strukturen in C einen eigenen Namensraum haben.
Walter T. schrieb:> In C würde ich es so machen:
Das geht auch in C++ so.
Walter T. schrieb:> oder auch:
Vorsicht! Das legt eine Variable namens libname_structname_t an. Das
ist sicher nicht, was Du erreichen möchtest.
Das zweite libname_structname_t hinter der geschlossenen Klammer muss
weg.
Walter T. schrieb:> Warum die Erweiterung mit dem Unterstrich?
Einen wirklichen Grund dafür gibt es nicht, das mag eine Gewöhnung des
Autors sein.
Tatsächlich kann man auch namenlose Strukturen zusammen mit typedef
verwenden und hat dann nicht den -überflüssigen- Strukturnamen:
Rufus Τ. F. schrieb:> Das zweite libname_structname_t hinter der geschlossenen Klammer muss> weg.
Stimmt. Copy-Paste-Fehler.
Rufus Τ. F. schrieb:> Einen wirklichen Grund dafür gibt es nicht, das mag eine Gewöhnung des> Autors sein.
Danke!
Rufus Τ. F. schrieb:> Tatsächlich kann man auch namenlose Strukturen zusammen mit typedef> verwenden
In einigen IDEs ist es praktisch, wenn alle structs Namen haben. Aber
ansonsten: Klar.
Tom schrieb:> Walter T. schrieb:>> Bei structs und andere Typen in unterschiedlichen namespaces sind, gibt>> es keine Kollision>> In der Steinzeit war das wohl noch nicht so:> https://blogs.msdn.microsoft.com/oldnewthing/20080326-00/?p=22993
Ich trau' Microsoft keinerlei Expertise hinsichtlich historischem C
zu.
Wenn ich mir bei Dennis Ritchie das C Reference Manual der 6th UNIX
Edition ansehe (von 1975):
https://www.bell-labs.com/usr/dmr/www/cman.pdf
… dann gibt es da sehr wohl bereits getrennte Namensräume für struct
tags und Variablen. Zu dieser Zeit dürfte Microsoft noch komplett in
Assembler programmiert haben.
Dafür gab es damals eine anderweitige Absonderlichkeit: die Elemente
von structs teilten sich alle einen Namensraum! Mit dieser Krücke
konnte man structs einrichten, deren erste Komponenten alle gleich
waren und einander Aliase bildeten – denn unions gab es offenbar noch
nicht.
Das erklärt, warum man in altem Unix-Sourcecode den struct-Elementen
immer einen oder zwei Buchstaben und einen Unterstrich vorangestellt
hat, bspw. st_mode oder st_ino in struct stat.
Jörg W. schrieb:> Ich trau' Microsoft keinerlei Expertise hinsichtlich historischem C> zu.
Aber in aktuellem C?
> Das erklärt, warum man in altem Unix-Sourcecode den struct-Elementen> immer einen oder zwei Buchstaben und einen Unterstrich vorangestellt> hat, bspw. st_mode oder st_ino in struct stat.
Aha! Ich hatte mich durchaus schon gefragt, wozu das gut sein soll, z.B.
auch bei der struct timeval mit tv_sec und tv_usec.
Rolf M. schrieb:>> Ich trau' Microsoft keinerlei Expertise hinsichtlich historischem C>> zu.>> Aber in aktuellem C?
Solange sich "aktuell" auf ANSI 89 / ISO 90 bezieht, ja. :)
Jörg W. schrieb:>> Aber in aktuellem C?>> Solange sich "aktuell" auf ANSI 89 / ISO 90 bezieht, ja. :)
Das mag für Microsoft noch immer als aktuell gelten, aber ich würde es
dann doch eher zum historischen C zählen. ;-)
Walter T. schrieb:> Ich verstehe allerdings nicht, was mit diesem Design Pattern bezweckt> werden soll.
Der einzige Zweck, der dahinter stehen mag ist der, daß der Autor das
Wort "struct" nicht bei den Variablendeklarationen hinschreiben will.
Also Faulheit, sonst nix.
Bedenke, daß "typedef" nichts anderes macht, als einem bekannten Typ
einen zweiten Namen zu geben, so daß man anschließend beide Namen für
denselben Typ verwenden kann.
Man hätte es besser "rename" nennen sollen.
Es unterscheidet sich vom #define nur dadurch, daß es an anderer Stelle
im Übersetzungsverlauf erledigt wird.
W.S.
W.S. schrieb:> Man hätte es besser "rename" nennen sollen.
Eher "Alias". Der alte Name existiert ja immer noch.
> Es unterscheidet sich vom #define nur dadurch, daß es an anderer Stelle> im Übersetzungsverlauf erledigt wird.
Und daher gibt es bei typedef auch keine Probleme mit Scope o.ä.
W.S. schrieb:> Es unterscheidet sich vom #define nur dadurch, daß es an anderer Stelle> im Übersetzungsverlauf erledigt wird.
Das ist Quatsch. Ein #define macht reine Textersetzung im Quellcode,
typedef arbeitet direkt im Typsystem. Dadurch ergeben sich bei #define
einige Fallstricke, und manche Sachen wie z.b. einen Namen für einen
Funktionszeiger-Typ kann man mit #define so gar nicht machen.
W.S. schrieb:> Der einzige Zweck, der dahinter stehen mag ist der, daß der Autor das> Wort "struct" nicht bei den Variablendeklarationen hinschreiben will.
Dafür allein würde aber
1
typedefstruct{...}foo_t;
genügen. Falls die struct sich selbst (über Zeiger) referenzieren
können muss, braucht sie unbedingt einen struct tag, aber dann geht
auch
1
typedefstructfoo_t{...}foo_t;
und man muss nicht unbedingt dieses unsinnige Doppelgemoppel mit dem
weiteren Unterstrich fabrizieren:
1
typedefstruct_foo_t{...}foo_t;
Nur um dieses ging ja der Thread.
Übrigens ist die zweite Variante oben sogar in C++ zulässig. Dort
würde ja bereits durch die struct selbst ein "foo_t" im entsprechenden
Namensraum erzeugt, aber die zusätzliche Erzeugung des gleichen Namens
mithilfe eines typedef ist explizit zugelassen. Dadurch kann man
entsprechende Headerfiles sowohl für C als auch C++ ohne Änderungen
oder #ifdef oder dergleichen benutzen.
W.S. schrieb:> Es unterscheidet sich vom #define nur dadurch, daß es an anderer Stelle> im Übersetzungsverlauf erledigt wird.
Das ist Unsinn, wie die meisten Deiner Aussagen zum Thema C.
1
#define d_ptr struct s *
2
typedefstructs*t_ptr;
Was ist der Unterschied?
1
d_ptrptr1,ptr2;
2
t_ptrptr3,ptr4;
Das Zweitere tut das, wonach es aussieht, zwei Pointer deklarieren. Aber
das Erstere macht Textersetzung, expandiert also zu:
1
structs*ptr1,ptr2;
Mit anderen Worten, ptr2 ist vom Typ struct s und nicht etwa ein Pointer
darauf. Wenn man defines zum typedefen mißbraucht, kriegt man solche
überraschenden Fehler raus.