struct Foo und typedef struct Foo_
-
Swordfish schrieb:
feigling schrieb:
Weils einfach so ist. Was für ne komische Frage .. Du könntest genauso fragen, warum der Kopf der for-Schleife genauso aufgebaut ist wie er ist und nicht anders.
Tolle Antwort
Die Frage ist schon berechtigt. Hab' ich eine Struct
struct tag_foo_t { int bar; }; // kann ich durch ein typedef struct tag_foo_t foo_t; // vermeiden, immer "struct" vor die Deklarationen von Instanzen der Struktur schreiben zu müssen: foo_t my_foo;
greetz, Swordfish
Deine ist aber auch nicht besser. Oder ich habe die Frage missverstanden. Ich habe unter der Frage verstanden, warum man bei nem struct immer "struct" vorschreiben muss, außer man hat ein typedef. Und die Antwort ist halt .. weils so vorgeschrieben ist O_o Die Frage war nicht, was der Unterschied zwischen den beiden Varianten ist ..
-
feigling hat vollkommen Recht. Der "tiefere Sinn", den du suchst, heißt Konvention.
-
T2.0 schrieb:
feigling hat vollkommen Recht. Der "tiefere Sinn", den du suchst, heißt Konvention.
Konvention ist der falsche Begriff. Es ist eine (harte) Regel die der ANSI/ISO-Standard aufstellt. Eine Konvention wäre z.B. dass getypedefte Typen das Anhängsel
_t
bekommen.
-
Haar in der Suppe?
-
Sind wir im Religionsunterricht?
"Weil es halt so ist, weil es halt so in der Bibel (der C-ISO-Standard) steht"Wieso wurde das so in den C-ISO-Standard aufgenommen? Hat man eine Muenze geworfen, Kopf ist das man "struct" vor dem Struct hinschreiben muss, bei Zahl nicht?
typedef ist da, um sich einen Datentyp zu erstellen, deswegen brauchst du das 'struct' danach nicht mehr, weil der Compiler dann weiß, dass es sich dabei um einen "struct {}" handelt.
Also der Compiler weis nicht das Foo ein struct ist, obwohl ich ihn als struct Foo {}; definiert habe?
-
DEvent schrieb:
Wieso wurde das so in den C-ISO-Standard aufgenommen? Hat man eine Muenze geworfen, Kopf ist das man "struct" vor dem Struct hinschreiben muss, bei Zahl nicht?
Philosophisch wäre genauso die Frage "wieso hätten sie es nicht so aufnehmen sollen". Daher bringt es absolut nichts sich darüber den Kopf zu zerbrechen. Vermutung meinerseits: Man hat einfach nicht die Möglichkeit bedacht, oder hat absichtlich nicht gewollt, dass ein Struct-Name gleichzeitig ein Typ-Name wird.
-
"struct" ist in C kein Typ. "struct name" aber schon (int == int, struct != struct).
-
LordJaxom schrieb:
Man hat einfach nicht die Möglichkeit bedacht, oder hat absichtlich nicht gewollt, dass ein Struct-Name gleichzeitig ein Typ-Name wird.
warum sollte man bei 'struct' eine ausnahme machen, wenn's z.b. bei 'enum' und 'union' anders wäre? das fände ich ziemlich inkonsistent und schliesslich, wer schreibfaul ist, der kann ja zu 'typedef' greifen.
anderseits würde es bestimmt funktionieren, wenn man struct/enum/union weglassen würde. ich kann mir keinen nachteil vorstellen, aber die iso/ansi-verfasser sind bestimmt schlauer als ich, denn sonst hätten sie's bestimmt anders gemacht.
-
DEvent schrieb:
Wieso wurde das so in den C-ISO-Standard aufgenommen? Hat man eine Muenze geworfen, Kopf ist das man "struct" vor dem Struct hinschreiben muss, bei Zahl nicht?
Der ISO-Standard ist von 1990, C ist in den 70ern entwickelt worden. Es dürfte einleuchten, dass man dort größtenteils keine neuen Entscheidungen getroffen hat, sondern existierende Implementationen als Grundlage genommen hat.
-
anderseits würde es bestimmt funktionieren, wenn man struct/enum/union weglassen würde. ich kann mir keinen nachteil vorstellen, aber die iso/ansi-verfasser sind bestimmt schlauer als ich, denn sonst hätten sie's bestimmt anders gemacht.
Vielleicht ist zu der Zeit als C entwickelt wurde auch einfach niemand auf die Idee gekommen, ein Struct-Tag auch gleich als Symbol in die Symboltabelle aufzunehmen, weil es nicht notwendig schien. In C++ wollte man vielleicht das Verhalten integraler Typen für Klassen (Operatorenüberladung etc.) imitieren.
Aber das ist und bleibt Spekulation, solange nicht jemand nen Interview mit den Mitgliedern des 1989er-ANSI-Komitees arrangiert
-
weglass-freak schrieb:
anderseits würde es bestimmt funktionieren, wenn man struct/enum/union weglassen würde.
Oh, struct und union brauche ich wirklich, die Alternativen wären wirklich BASIC- mäßig zerfledderte Konstruktionen.
Wenn ich ehrlich bin, habe ich außer zu akademischen Zwecken (mal probiert halt) noch nie typedef oder enum eingesetzt, die waren wirklich verzichtbar. Enumerationen bilde ich per define ab, structs und Funktionspointer schreibe ich lieber aus, damit mir auch später klar ist: Hoppla, denk' nach, was Du da tust.Asche über mein Haupt, wenn ich da dem C- Puristen auf die Zehen latsche, aber da ich nie aufhören möchte, zu lernen: Inwiefern sollen typedef und enum unverzichtbar sein?
-
pointercrash() schrieb:
Enumerationen bilde ich per define ab,
geht ja auch, aber ich finde bei enums das automatische hochzählen praktisch und dass der compiler meckert, wenn man hardcodierte werte doppelt hat. bei #defines haste ja diese compilerunterstützung nicht.
pointercrash() schrieb:
structs und Funktionspointer schreibe ich lieber aus...
naja, es gibt schon echt fiese konstruktionen, die ohne 'typedef' super-hässlich und unleserlich sind.
pointercrash() schrieb:
Inwiefern sollen typedef und enum unverzichtbar sein?
das sagt ja keiner. ich meinte das
enum lala { A,B,C }; union puh { int a; char c; }; ... enum lala l; union puh p; ...
also beim anlegen von instanzen muss man 'enum' und 'union' hinschreiben, sonst frisst's der compiler nicht. normalerweise aber könnte es auch ohne gehen. ich wüsste jedenfalls keinen nachteil, ausser einer vielleicht schlechteren lesbarkeit. aber die hat man ja auch, wenn man's 'typedef'd' und miese typnamen wählt.
-
naja, es gibt schon echt fiese konstruktionen, die ohne 'typedef' super-hässlich und unleserlich sind.
In C gehts ja noch, aber in C++ wirds wegen Templates schon unuebersichtlich.
-
DEvent schrieb:
naja, es gibt schon echt fiese konstruktionen, die ohne 'typedef' super-hässlich und unleserlich sind.
In C gehts ja noch, aber in C++ wirds wegen Templates schon unuebersichtlich.
mag sein, aber auf c++ kann man zum glück so gut wie immer verzichten.
-
pointercrash() schrieb:
Inwiefern sollen typedef und enum unverzichtbar sein?
Unverzichtbar sicher nicht. Aber ein typedef ist u.a. sehr geschickt weil man manchmal halt eben die Implementierung hinter dem Typ verstecken will. Beispiel
FILE
. Man braucht überhaupt nicht zu wissen was sich dahinter verbirgt, struct, union, bitfield, int. Alles läuft über die gegebenen Schnittstellen (fopen, fclose, fwrite, ...) ab.
-
es ist doch ein essentieller Unterscheid, ob ich von C oder von C++ rede, oder nicht? Das eine ist eine prozedurale Programmiersprache aus den 70er Jahren, mit der ich absolut Speicher und CPU effizient Coden kann - damals hat man auch die Notwenigkeit dafür noch gehbat. Zu Zeiten von C++ und C#, was nunmal der Objektorientierung angehört wird kaum mehr Wert auf Ressourceneffizienz gelegt. Man kann allerdings objektorientiert viel schneller kompelxe Programme stricken, ohne sich Gedanken machen zu müssen, wie kopmlexe Datentypen intern aussehen, wie sie behandelt werden müssen usw.! Die Anforderungen haben sich also im Laufe der von Ressourcenknappheit auf der hardwareseite nach Zeitknappheit bei der Entwicklung verlagert - und daraus resultiert nun mal eine vereinfachte Benutzung der Programmiersprache bei der gleichen Aufgabenstellung.
Und zu dem struct / enum oder typedef und nicht struct / enum: wenn man professionell programmiert und dabei auf eine gewisse Lesbarkeit und Wiederverwendbarkeit der eigenen Quelltexte achten muss kann man sicherlich auch die typedefs nicht allzu gut einsetzen, um dem "Wiederverwender" zu ermöglichen, den Quelltext sauber zu lesen ohne erst jedes Header-File studieren zu müssen. Wenn man allerdings privat codet und weiß, man wird nur selbst jemals den Quelltext zu Gesicht bekommen und man kann sich merken, wie man seine eigenen Datentypen, Strukturen, Enumerationen und so weiter definiert hat, dann kann man sie ja durchaus dem Compiler auch mit typedef bekannt geben.
Soviel zu meiner Meinung zu dem Thema - ob sie nun einer wissen will oder nicht!
-
@ Tim:
Das Problem dabei ist: FILE ist Well-Known und kann überall nachgeschaut werden. Wenn ich mir allerdings jetzt selbst eine Structur schreibe, die beispielsweise einen Mitarbeiter mit allen Attributen definiere sollte ich einem potenziellen Leser meines Codes schon die Möglichkeit geben, nach zu vollziehen, was ich tue und wie, oder meinst du nicht?
-
AnonymousCoder schrieb:
es ist doch ein essentieller Unterscheid, ob ich von C oder von C++ rede, oder nicht?
Wir sind hier im C-Unterforum, von daher ist klar worüber wir reden. Womit ich den weiteren Absatz (den du btw. nochmal überdenken solltest) nicht weiter kommentieren werde.
AnonymousCoder schrieb:
Und zu dem struct / enum oder typedef und nicht struct / enum: wenn man professionell programmiert und dabei auf eine gewisse Lesbarkeit und Wiederverwendbarkeit der eigenen Quelltexte achten muss kann man sicherlich auch die typedefs nicht allzu gut einsetzen, um dem "Wiederverwender" zu ermöglichen, den Quelltext sauber zu lesen ohne erst jedes Header-File studieren zu müssen.
Bezüglich der Lesbarkeit: Das ist im Zweifelsfall eine Meinungssache und hat mit "professioneller Programmierung" erstmal nichts zu tun. Aber wenn du Header-Files lesen musst, um einen Typen genauer zu identifizieren (Struktur, Enumeration, plain int, ...) dann fehlt dem Projekt zumindest ein Aspekt der "professionellen Programmierung", nämlich eine ordentliche Doku. Und in der musst du so oder so nachschauen, wenn du wissen willst was ein Typ T genau ausmacht (welche Member, welche Konstanten kennt das enum, ...), egal ob du nun schon weisst dass es ein struct oder ein enum oder sonstwas ist.
Bezüglich der Wiederverwendbarkeit: Du schreibst ein Modul welches andere Entwickler benutzen müssen. Denken wir an ein theoretisches Objekt (z.B. etwas wie ein FILE) mit dem die Leute arbeiten. Wir nennen es
struct obj
, mit dem Konstruktorstruct obj *obj_init(void)
, dem Destruktorvoid obj_kill(struct obj *object)
und ein paar anderen Methoden wie z.B.void obj_send_data(struct obj *object, int data)
. Nun kann es im Laufe der Entwicklung passieren, dass sich deine Implementierung ändert, so merkst du (aus welchen Gründen auch immer) dass die Implementierung alsstruct obj
Nachteile hat und willst nur noch eine ID (vom Typ int z.B.) in der Schnittstelle verwenden. Natürlich musst du nun alle deine Funktionen anpassen, aber viel schlimmer noch, die Benutzer deines Moduls müssen es ebenfalls. Hättest du von Anfang an eintypedef struct obj obj_t
benutzt, könntest du jetzt einfach eintypedef int obj_t
machen und die Schnittstelle hat sich nicht geändert.
-
AnonymousCoder schrieb:
es ist doch ein essentieller Unterscheid, ob ich von C oder von C++ rede, oder nicht? Das eine ist eine prozedurale Programmiersprache aus den 70er Jahren, mit der ich absolut Speicher und CPU effizient Coden kann - damals hat man auch die Notwenigkeit dafür noch gehbat.
glaubst du wirklich, dass diese notwendigkeit heute nicht mehr besteht?
C ist zwar ein steinalter hund, aber auf dem gebiet der hardwarenahen system- und low-level programmierung auch heute noch unersetzlich.
-
AnonymousCoder schrieb:
@ Tim:
Das Problem dabei ist: FILE ist Well-Known und kann überall nachgeschaut werden. Wenn ich mir allerdings jetzt selbst eine Structur schreibe, die beispielsweise einen Mitarbeiter mit allen Attributen definiere sollte ich einem potenziellen Leser meines Codes schon die Möglichkeit geben, nach zu vollziehen, was ich tue und wie, oder meinst du nicht?
Wieso sollte es bei einem FILE anderes sein als mein eigenes Object FOO?
Ich weis z.B. absolut nicht was sich hinter FILE versteckt, interessiert mich auch nicht im geringstem. Ich weis nur das ich es braucht fuer fopen(), fclose() usw. und wenn ich irgendwann eine foo(FILE* file) habe, dann gehe ich davon aus das derjenige der foo() implementiert hat, genau weis wie man FILE benutzt.
Aber schoen das man mir die Frage beantwortet hat ob man
struct Foo {} // oder typedef struct _Foo {} Foo;
schreiben soll. Werd bei naechster Gelegenheit meine Programme auf letzeres umstellen.
Uebrigens programmiere ich in C (fast) genauso Objectorientiert wie in Java/C++. Mir fehlt da nur dass man keine privaten Attribute in C hat, bzw. ich weis nicht wie man private Attribute am besten implementieren kann.