Forum: PC-Programmierung typedef in C


von Georg (Gast)


Lesenswert?

Hallo zusammen,

ich habe in einer Datei mit dem Namen my_types.h folgendes stehen:
1
typedef struct A_ {
2
  uint8 a;
3
  uint8 b;
4
} A;

Nun gibt es in meinem Projekt mehrere .c Dateien, welche den Typ A 
verwenden. Deshalb habe ich oben in jeder dieser .c Datein oben #include 
"my_types.h" eingetragen.
Beim compilieren bekomme ich jetzt den Fehler, dass der Typ A bereits 
deklariert sei (was ja auch stimmt, weil die my_types.h ja auch für jede 
.c Datei eingebunden wird). Wie kann ich dieses Problem umgehen?

: Verschoben durch Moderator
von Rolf M. (rmagnus)


Lesenswert?

Georg schrieb:
> Beim compilieren bekomme ich jetzt den Fehler, dass der Typ A bereits
> deklariert sei (was ja auch stimmt, weil die my_types.h ja auch für jede
> .c Datei eingebunden wird).

Das Problem entsteht nicht dadurch, dass es in mehreren .c-Dateien 
eingebunden ist, sondern dass es in einer .c-Datei mehrfach eingebunden 
ist.
Stichwort wäre "include guard".

: Bearbeitet durch User
von Georg (Gast)


Lesenswert?

Tatsächlich, damit gehts! Vielen Dank!

von fop (Gast)


Lesenswert?

Ich hätte ja darauf getippt, dass der Namen für den Typ zu kurz ist und 
deshalb zufällig noch für einen anderen Typ herhalten musste.
Ich bin ja auch tippfaul, aber ein wenig mehr geht schon.

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


Lesenswert?

Georg schrieb:

>
1
> typedef struct A_ {
2
>   uint8 a;
3
>   uint8 b;
4
> } A;
5
>

Wenn du das Dingens sowieso nie als „struct A_“ benutzen willst, kannst 
du den struct-Namen auch getrost weglassen. Der verunreinigt nur 
unsinnig den Namensraum. Wenn man als generelle Policy alles mit 
typedefs abwickelt, braucht man struct-Namen eigentlich nur, um 
innerhalb der struct-Definition selbst schon darauf zugreifen zu können 
(in Form eines Zeigers).

Außerdem wäre es auch völlig legitim, das Dingens „struct A“ zu nennen. 
In C haben structs einen vom Rest getrennten Namensraum (man definiert 
damit also ein „A“ sowohl im allgemeinen als auch im struct-Raum). In 
C++ wiederum begründet „struct A“ einen Namen „A“, der auch ohne das 
Schlüsselwort „struct“ fürderhin benutzt werden darf, ganz ohne typedef 
- aber ein gleichnamiger typedef ist dennoch gestattet.

von Name, Name, Namen (Gast)


Lesenswert?

Nein! Bitte keine namenlosen Strucks und Co. ???

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Gibt es auch irgendwelche Argumente?

von Framulestigo (Gast)


Lesenswert?

Die drei gesenkten Daumen sollten Dir reichen. :)
(Nero halt)

Sollte man vielleicht in diesem Zusammenhang noch etwas über das 
typische "#ifndef" im Header sagen?

von A. S. (Gast)


Lesenswert?

Framulestigo schrieb:
> Die drei gesenkten Daumen sollten Dir reichen. :)
> (Nero halt)

Die Aussage ist aber Quatsch. Wenn ein Strukturname nicht gebraucht wird 
(nie, gar nicht), dann ist der Name über flüssig.

> Sollte man vielleicht in diesem Zusammenhang noch etwas über das
> typische "#ifndef" im Header sagen?

Die Frage war schon lange, ausreichend und richtig beantwortet.

Beitrag #5659093 wurde von einem Moderator gelöscht.
von Markus K. (markus-)


Lesenswert?

Ich habe schon öfters gesehen, dass die Compiler sich in den 
Fehlermeldungen dann auf die anonymen structs bezogen haben. Also sowas 
wie
struct unknown4711 has no member x

Deswegen bin ich auch eher dafür, keine anonymen structs zu haben.

Ich kann gerade leider nicht mehr sagen, welche Compiler das waren 
(vielleicht IAR oder TI CCS?). Zuhause habe ich auf die Schnelle mit 
Visual Studio 2017 und Mingw 5.30 getestet und die geben vernünftige 
Fehlermeldungen aus.

von mh (Gast)


Lesenswert?

Markus K. schrieb:
> Ich habe schon öfters gesehen, dass die Compiler sich in den
> Fehlermeldungen dann auf die anonymen structs bezogen haben. Also sowas
> wie
> struct unknown4711 has no member x
>
> Deswegen bin ich auch eher dafür, keine anonymen structs zu haben.

Das ist natürlich nicht schön. Der Compiler sollte zumindest in der Lage 
sein, den Namen des neuen Typs in der Fehlermeldung zu nennen. 
Alternativ sowas wie "anonymous struct". Wenn er das nicht macht ist das 
mindestens nen Bugreport wert. Aber ein vernünftiger Compiler gibt ja 
auch die Zeilennummer bei der Fehlermeldung an, so dass es nicht so 
tragisch ist, da man den Fehler ja eh vor Ort beheben muss. Ich sehe da 
keinen Grund gegen anonyme Strukturen.

von Markus K. (markus-)


Lesenswert?

mh schrieb:
> Markus K. schrieb:
>> Ich habe schon öfters gesehen, dass die Compiler sich in den
>> Fehlermeldungen dann auf die anonymen structs bezogen haben. Also sowas
>> wie
>> struct unknown4711 has no member x

> Aber ein vernünftiger Compiler gibt ja
> auch die Zeilennummer bei der Fehlermeldung an, so dass es nicht so
> tragisch ist, da man den Fehler ja eh vor Ort beheben muss.

Wenn der Code ein a.x = f.x ist (zwei verschiedene Structs, gleicher 
Membername), dann ist das halt erst der Startpunkt. Dann muss man 
erstmal rausfinden, welches der beiden Structs das war. Wenn das dann 
verschachtelte Structs sind (a.b.c.x = d.e.f.x) und die Unterstützung 
der IDE nicht funktioniert (also kein "Cursor auf die Variable und F10 
drücken", z.B. weil man eine fremde Buildumgebung in ein Visual Studio 
gepackt hat), dann passiert es schnell, dass man sich durch eine 
handvoll header files kämpfen darf bis sieht wo es klemmt. Was man auch 
hätte vermeiden können, wenn wenn man keine anonymen Structs benutzt 
hätte.

von Vn N. (wefwef_s)


Lesenswert?

Markus K. schrieb:
> Ich kann gerade leider nicht mehr sagen, welche Compiler das waren
> (vielleicht IAR oder TI CCS?).

Zumindest ist TI dafür berüchtigt, seine hauseigenen Compiler nicht.im 
Griff zu haben...

von mh (Gast)


Lesenswert?

Markus K. schrieb:
> Wenn der Code ein a.x = f.x ist (zwei verschiedene Structs, gleicher
> Membername), dann ist das halt erst der Startpunkt. Dann muss man
> erstmal rausfinden, welches der beiden Structs das war. Wenn das dann
> verschachtelte Structs sind (a.b.c.x = d.e.f.x) und die Unterstützung
> der IDE nicht funktioniert (also kein "Cursor auf die Variable und F10
> drücken", z.B. weil man eine fremde Buildumgebung in ein Visual Studio
> gepackt hat), dann passiert es schnell, dass man sich durch eine
> handvoll header files kämpfen darf bis sieht wo es klemmt. Was man auch
> hätte vermeiden können, wenn wenn man keine anonymen Structs benutzt
> hätte.

Also ein "vierfach wenn" (wenn Membernamen nichtssagend und wenn 
geschachtelte anonyme Strukturen und wenn fehlende Unterstützung durch 
die IDE und wenn mangehafte Fehlermeldung vom Compiler dann verursachen 
anonyme Strukturen etwas mehr Arbeit). Wenn ich mit dir zusammen 
arbeiten würde, würdest du mich damit nicht überzeugen.

von Carl D. (jcw2)


Lesenswert?

mh schrieb:
> Markus K. schrieb:
>> Wenn der Code ein a.x = f.x ist (zwei verschiedene Structs, gleicher
>> Membername), dann ist das halt erst der Startpunkt. Dann muss man
>> erstmal rausfinden, welches der beiden Structs das war. Wenn das dann
>> verschachtelte Structs sind (a.b.c.x = d.e.f.x) und die Unterstützung
>> der IDE nicht funktioniert (also kein "Cursor auf die Variable und F10
>> drücken", z.B. weil man eine fremde Buildumgebung in ein Visual Studio
>> gepackt hat), dann passiert es schnell, dass man sich durch eine
>> handvoll header files kämpfen darf bis sieht wo es klemmt. Was man auch
>> hätte vermeiden können, wenn wenn man keine anonymen Structs benutzt
>> hätte.
>
> Also ein "vierfach wenn" (wenn Membernamen nichtssagend und wenn
> geschachtelte anonyme Strukturen und wenn fehlende Unterstützung durch
> die IDE und wenn mangehafte Fehlermeldung vom Compiler dann verursachen
> anonyme Strukturen etwas mehr Arbeit). Wenn ich mit dir zusammen
> arbeiten würde, würdest du mich damit nicht überzeugen.

Die Lösung wäre, im Zweifel, um garantiert in jeder Hinsicht portabel zu 
sein, nur den kleinsten gemeinsamen Nenner aus möglichen Compilern, 
möglichen IDEs und möglichen Programmierern zu benutzen.

Zum Glück ist das keine verbindliche Regel.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Carl D. schrieb:
> Die Lösung wäre, im Zweifel, um garantiert in jeder Hinsicht portabel zu
> sein, nur den kleinsten gemeinsamen Nenner

Das wäre K&R-C, also C noch vor C89.

von Markus K. (markus-)


Lesenswert?

mh schrieb:

> Also ein "vierfach wenn" (wenn Membernamen nichtssagend

Das funktioniert leider auch mit guten Namen. Immer wenn man in zwei 
verschiedenen Structs members mit dem gleichen Namen benutzt, z.B. weil 
damit das selbe gemeint ist.

> und wenn geschachtelte anonyme Strukturen

Die Prämisse in der Diskussion war doch, dass man alle Strukturen anonym 
macht. Dann sind auch die geschachtelten Strukturen anonym.

> und wenn fehlende Unterstützung durch die IDE und
> wenn mangehafte Fehlermeldung vom Compiler dann verursachen
> anonyme Strukturen etwas mehr Arbeit).


> Wenn ich mit dir zusammen
> arbeiten würde, würdest du mich damit nicht überzeugen.

Dann wären das a) auch Deine Probleme, also kein absurder Spezialfall, 
sondern Dein Arbeitsalltag und b) war das Argument FÜR anonyme 
Strukturen, dass man so den Namensraum sauber hält - aber wenn man keine 
IDE-Unterstützung hat, dann spielt das m.M. nach eh keine Rolle.

von (prx) A. K. (prx)


Lesenswert?

Rufus Τ. F. schrieb:
>> Die Lösung wäre, im Zweifel, um garantiert in jeder Hinsicht portabel zu
>> sein, nur den kleinsten gemeinsamen Nenner
>
> Das wäre K&R-C, also C noch vor C89.

Mitnichten. Der Schritt von K&R- zu ANSI-C führte zu wesentlich 
verbesserter Portabilität. Die Sprache war davor zu schwach definiert, 
was zu inkompatiblen Compilern führte.

Ich würde auch nicht drauf wetten, dass jeder Compiler überhaupt noch 
K&R akzeptiert.

: Bearbeitet durch User
von mh (Gast)


Lesenswert?

Markus K. schrieb:
> Das funktioniert leider auch mit guten Namen. Immer wenn man in zwei
> verschiedenen Structs members mit dem gleichen Namen benutzt, z.B. weil
> damit das selbe gemeint ist.

Aber es ist nur ein Problem, wenn auch die anderen "wenns" erfüllt sind.

Markus K. schrieb:
> Die Prämisse in der Diskussion war doch, dass man alle Strukturen anonym
> macht. Dann sind auch die geschachtelten Strukturen anonym.

Es ging ursprünglich nur um die struct A_.

Markus K. schrieb:
> Dann wären das a) auch Deine Probleme, also kein absurder Spezialfall,
> sondern Dein Arbeitsalltag und b) war das Argument FÜR anonyme
> Strukturen, dass man so den Namensraum sauber hält - aber wenn man keine
> IDE-Unterstützung hat, dann spielt das m.M. nach eh keine Rolle.

Klar wäre es dann auch mein Problem. Aber ich würde das Problem eher 
über eins der anderen "wenns" lösen. Ein besserer Compiler kann ein 
Problem sein, aber eine bessere IDE?

von A. S. (Gast)


Lesenswert?

Markus K. schrieb:
> Die Prämisse in der Diskussion war doch, dass man alle Strukturen anonym
> macht. Dann sind auch die geschachtelten Strukturen anonym.

Nein. wieso sollten die Anonym sein? Es ging nur um Typedefs.

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.