Forum: PC-Programmierung typedef in C


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Georg (Gast)


Bewertung
-2 lesenswert
nicht 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)


Bewertung
3 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Tatsächlich, damit gehts! Vielen Dank!

von fop (Gast)


Bewertung
0 lesenswert
nicht 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


Bewertung
1 lesenswert
nicht 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)


Bewertung
-2 lesenswert
nicht lesenswert
Nein! Bitte keine namenlosen Strucks und Co. ???

von Rufus Τ. F. (rufus) (Moderator) Benutzerseite


Bewertung
4 lesenswert
nicht lesenswert
Gibt es auch irgendwelche Argumente?

von Framulestigo (Gast)


Bewertung
0 lesenswert
nicht 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. (achs)


Bewertung
0 lesenswert
nicht 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-)


Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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-)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht 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-)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (achs)


Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.