hallo,
beim compilierem meines Programmes stoße ich mich an der Fehlermeldung
conflicting types for 'val_printf'. obwohl ich die Funktion im
header-datei folgendes deklariert habe: static void val_printf(struct
tval *).
hätte einer eine Idee wie ich das problem beheben könnte?
PS: ich arbeite mit Eclipse und MinGW
struct tval
{
union
{
float x;
float y;
uint16_t z;
}val;
int typ;
};
static void val_printf(struct tval *message_Id)
{
switch(message_Id -> typ)
{
case x:
case y:
case z:
}
}
Kaiser K. schrieb: > obwohl ich die Funktion im > header-datei folgendes deklariert habe: static void val_printf(struct > tval *). Wozu eine static-Funktion im Header deklarieren? Andere Module (.c-Dateien) können ohnehin nicht drauf zugreifen.
Ohne Gewähr: muss evtl. im .h vor der Deklaration noch "extern" stehen.
Da sind sicher noch andere Fehlermeldungen. Weiß denn der Header wo "struct tval" definiert ist?
Beitrag #5545454 wurde von einem Moderator gelöscht.
. . schrieb im Beitrag #5545444: > Da sind sicher noch andere Fehlermeldungen. > Weiß denn der Header wo "struct tval" definiert ist? es gibt zwar andere Fehlermeldungen wie z.B.'val_printf' declared 'static' but never defined. oder 'struct tval' declared inside parameter list will not be visible outside of this declaration or definition; aber ich denke die sind an die erste meldung verbunden
Hast Du sichergestellt, dass das Headerfiles nicht mehrmals vom Preprocessor eingefügt wird? e.g.
1 | #ifndef myfile_h
|
2 | #define myfile_h
|
3 | |
4 | <mein kram> |
5 | |
6 | #endif // myfile_h
|
Grüsse, René
lass mal das struct weg static void val_printf(tval *message_Id)
Domi schrieb: > lass mal das struct weg > > static void val_printf(tval *message_Id) Dann geht's gar nicht in C. Witzig, wie hier wieder mit Halbwissen herumgeraten wird. Es fehlt jedenfalls mal der komplette Sourcecode, insbesondere der Header. Das Hauptproblem ist aber natürlich, dass der Sinn von "static" nicht verstanden wurde - eine static-Funktion in einen Header zu packen ist ziemlich sinnlos. "extern" an Funktionen ist übrigens komplett überflüssig (hat keinerlei Wirkung).
Dr. Sommer schrieb: > "extern" an Funktionen ist > übrigens komplett überflüssig (hat keinerlei Wirkung) ...in diesem speziellen Fall oder allgemein?
Domi schrieb: > lass mal das struct weg > > static void val_printf(tval *message_Id) funktionniert leider nicht
50c schrieb: > ...in diesem speziellen Fall oder allgemein? In C ist extern bei Funktionsprototypen das implizite Gegenteil von static und kann daher immer wegfallen.
Dr. Sommer schrieb: > Domi schrieb: >> lass mal das struct weg >> >> static void val_printf(tval *message_Id) > > Dann geht's gar nicht in C. Witzig, wie hier wieder mit Halbwissen > herumgeraten wird. Es fehlt jedenfalls mal der komplette Sourcecode, > insbesondere der Header. das ist der Coder #define V 0 #define W 1 #define X 2 #define Y 3 #define Z 4 struct tval { int typ; union { float v; float y; uint16_x; uint16_t y; uint32_t z; }val; }; static void val_printf(struct tval *message_Id) { switch(message_Id -> typ) { case V: printf("v = %.2f\n", message_Id -> val.v); break; case W: printf("x = %.2f\n", message_Id -> val.w); break; case X: printf("x= %i\n", message_Id -> val.x); break; case Y: printf("y = %i\n", message_Id -> val.y); break; case Z: printf("z = %i\n", message_Id -> val.z); break; } } das ist mein Header #ifndef PROTOCOL_H_ #define PROTOCOL_H_ static void val_printf(struct tval *); #endif /* PROTOCOL_H_ */
Kaiser K. schrieb: > static void val_printf(struct tval *); An der Stelle ist "tval" nicht definiert. Daher kommt hier ein Fehler. Das "struct tval" muss im Header definiert werden. Noch einmal die Frage: Warum eine "static" Funktion im Header deklarieren? Was soll das bezwecken?
Kaiser K. schrieb: > oder 'struct tval' declared inside > parameter list will not be visible outside of this declaration or > definition; Dies besagt, dass die zuerst innerhalb der Parameter auftauchende Deklaration der Strukt eine andere Strukt ist als die global definierte. Dies sind also zwei inkompatible Deklarationen: void f(struct s *); struct s; // zwei verschiedene structs struct s; void f(struct *); // zweimal die gleiche struct
Dr. Sommer schrieb: > An der Stelle ist "tval" nicht definiert. Daher kommt hier ein Fehler. > Das "struct tval" muss im Header definiert werden. Eine forward declaration als struct tval; reicht bei einem Pointer darauf aus. Nur darf die erste Erwähnung davon nicht in einer Paramterdeklaration erfolgen.
...du musst den struct tval als Typ definieren (in der Header-Datei) und dann mit diesem Typ bei den Deklarationen arbeiten
tval.w ist nicht und ob in der Union 2 y möglich sind? "w" wird auch nie geprinted.
50c schrieb: > ...du musst den struct tval als Typ definieren (in der Header-Datei) und > dann mit diesem Typ bei den Deklarationen arbeiten Kann man machen, muss man aber nicht.
Dr. Sommer schrieb: > Noch einmal die Frage: > Warum eine "static" Funktion im Header deklarieren? Was soll das > bezwecken? also ohne diese Funktion zu deklarieren bekomme ich als fehlermeldung : undefined reference to 'val_printf'
Mr. OCD schrieb: > tval.w ist nicht und ob in der Union 2 y möglich sind? > "w" wird auch nie geprinted. das ist nur schreibfehler
Natürlich interessiert das hier keinen Menschen, aber so könnte das in der Arduino C++ Welt aussehen Dass das C werden soll, stand nicht im Eingangsposting... Darum, wenn ich mir schon die Arbeit gemacht habe, hier die Show, im Anhang.
Kaiser K. schrieb: > also ohne diese Funktion zu deklarieren bekomme ich als fehlermeldung : > undefined reference to 'val_printf' Kann nicht sein. Höchstens wenn du sie nicht definierst.
Dank "static" kannst du die Funktion nur von der selben Source (.c) Datei aus aufrufen, wie die in der sie definiert ist. Mit einer Deklaration im Header kann man sie aus anderen Dateien aus aufrufen, was aber nicht klappt (static ist "stärker"). Was von beiden willst du? Was du da schreibst ist "rote grüne Ampel".
Schreib mal deinen Header so:
1 | #ifndef PROTOCOL_H_
|
2 | #define PROTOCOL_H_
|
3 | |
4 | struct tval |
5 | {
|
6 | int typ; |
7 | union
|
8 | {
|
9 | float v; |
10 | float y; |
11 | uint16_x; |
12 | uint16_t y; |
13 | uint32_t z; |
14 | }val; |
15 | };
|
16 | |
17 | static void val_printf(struct tval *); |
18 | |
19 | #endif /* PROTOCOL_H_ */ |
merciless
static-forward-Deklarationen gehören in den Kopf der C-Datei und NICHT in den Header! Lesen, was Dr. Sommer schreibt!
Dr. Sommer schrieb: > Kann nicht sein. Höchstens wenn du sie nicht definierst. definieren meinte ich sorry
Kaiser K. schrieb: > definieren meinte ich sorry Ja, definieren musst du sie natürlich. Aber warum deklarierst du sie in der Header-Datei?
Mach das 'static' weg, füge eine forward-deklaration ein und gut. Dein Header sieht dann so aus:
1 | #ifndef PROTOCOL_H_
|
2 | #define PROTOCOL_H_
|
3 | |
4 | struct tval; |
5 | void val_printf(struct tval *); |
6 | |
7 | #endif /* PROTOCOL_H_ */ |
Und in der C-Datei machst du das 'static' auch weg. Wenn du eine Funktion im Header erwähnst, dann gehört sie zur öffentlichen Schnittstelle des Moduls und ist nicht static. Wenn sie nicht zur öffentlichen Schnittstelle gehört, dann ist sie static und steht nicht im Headerfile.
Als Anfänger, und so lange man die Funktion von static noch nicht verstanden hat, kann man i.d.R. auch ohne static gut leben.
Beitrag #5545657 wurde von einem Moderator gelöscht.
Rufus Τ. F. schrieb: > In C ist extern bei Funktionsprototypen das implizite Gegenteil von > static und kann daher immer wegfallen. Kann aber MUSS aber nicht. Aus Gründen der Einheitlichkeit, auch der visuellen Einheitlichkeit kommt bei mir nicht nur bei externen Daten, sondern auch bei externen Funktionen das extern dran. Das spart einem das Suchen, ob das nun was Externes oder bloß ne Vorwärtsdeklaration in derselben Quelle ist. W.S.
W.S. schrieb: > Das spart einem das Suchen, ob das nun was > Externes oder bloß ne Vorwärtsdeklaration in derselben Quelle ist. Das ist reine Geschmackssache - dem Compiler ist es egal.
W.S. schrieb: > Das spart einem das Suchen, ob das nun was > Externes oder bloß ne Vorwärtsdeklaration in derselben Quelle ist. Externes gehört sowieso in Header. In C-Dateien gehören nur Vorwärtsdeklarationen, die in der selben Datei definiert sind. Sonst handelt man sich nur Probleme ein; wenn man die Signatur der Funktion ändert, und vergisst irgendwo die "extern"-Deklaration zu ändern, bekommt man lustige Laufzeit-Probleme. Bei Dingen im Header ist sowieso klar dass sie etwas externes referenzieren. Mamas Liebling schrieb im Beitrag #5545657: > Super. 12 Zeilen in C und 120 unterschiedliche Ansichten dazu, was > richtig ist und was nicht. Leider lernt keiner C richtig (insb. Ing.-Studenten) aber jeder meint es zu beherrschen...
S. R. schrieb: > Wenn sie > nicht zur öffentlichen Schnittstelle gehört, dann ist sie static und > steht nicht im Headerfile. Stimmt so nicht ganz. Wenn sie nicht explizit als static deklariert wurde, kann man immer noch mit
1 | extern void val_printf(struct tval *); |
drauf zugreifen. C hat eben kein wirklich sauberes Modulkonzept, das muß man leider hinnehmen. W.S.
Dr. Sommer schrieb: > Externes gehört sowieso in Header. Auch wieder falsch. In Headerdateien kommt - oder besser: sollte eigentlich kommen - NUR das, was man in der zugehörigen Quelle zum Veröffentlichen vorgesehen hat. Also richtig herum: Internes, was man veröffentlichen will, gehört in die Headerdatei. Leider sieht man fast immer Headerdateien, wo deren Autoren allen möglichen und unmöglichen Prassel hineingestopft haben. W.S.
W.S. schrieb: > Leider sieht man fast immer Headerdateien, wo deren Autoren allen > möglichen und unmöglichen Prassel hineingestopft haben. Kann ja sein. Das ist aber überhaupt kein Grund, in C-Dateien Vorwärtsdeklarationen für andere C-Dateien zu packen.
Statt dem TO in seinem Lernprozess zu unterstützen, geht jetzt wieder die übliche "Korinthenkackerei" los.... Und das nur, weil Manche sich unbedingt als "C-Versteher" profilieren müssen.
W.S. schrieb: > Aus Gründen der Einheitlichkeit, auch der visuellen Einheitlichkeit > kommt bei mir Daß Du einen sehr spezifischen C-Stil hast, ist bekannt. "extern" vor Funktionsprototypen irritiert, da das sonst annähernd niemand* macht und somit damit versehener Code ... exotisch ist. *) ich lese seit bald 30 Jahren C-Sourcen der verschiedensten Quellen
Rufus Τ. F. schrieb: > W.S. schrieb: >> Aus Gründen der Einheitlichkeit, auch der visuellen Einheitlichkeit >> kommt bei mir > > Daß Du einen sehr spezifischen C-Stil hast, ist bekannt. > > "extern" vor Funktionsprototypen irritiert, da das sonst annähernd > niemand* macht und somit damit versehener Code ... exotisch ist. > > > *) ich lese seit bald 30 Jahren C-Sourcen der verschiedensten Quellen +1
Beitrag #5545723 wurde von einem Moderator gelöscht.
Beitrag #5545903 wurde von einem Moderator gelöscht.
Beitrag #5545914 wurde von einem Moderator gelöscht.
Gibts irgendeine Programmiersprachen, welche einen nicht bekloppt macht...? Jetzt mal Lisp und Forth ausgenommen, denn die sind voll normal.
> Man muß nur lange genug C-Code lesen, um irgendwann meschugge zu werden. > Es nötigt ihm daher Respekt ab, daß das bei Rufus offensichtlich (noch) > nicht der Fall ist. Plot twists und andere Hypothesen: - man kann 30J lang /hello, world!/ und sonstigen Trivialcode aus Foren lesen und immernoch nicht verstehen (kurzer Horizont oder so) - soviel anständigen C Quellcode gibt es gar nicht (versuch eine urbane Legende zu etablieren) scnr
Arduino Fanboy D. schrieb: > Gibts irgendeine Programmiersprachen, welche einen nicht bekloppt > macht...? brainfuck
S. R. schrieb: > Mach das 'static' weg, füge eine forward-deklaration ein und gut. > > Dein Header sieht dann so aus: >
1 | > #ifndef PROTOCOL_H_ |
2 | > #define PROTOCOL_H_ |
3 | >
|
4 | > struct tval; |
5 | > void val_printf(struct tval *); |
6 | >
|
7 | > #endif /* PROTOCOL_H_ */ |
8 | >
|
>
das hat geklappt... Danke.
ich hätte noch eine weitere Frage.
also beim schreiben des Programmes habe ich eine variable struct tval
myval deklariert und die funktion mit val_printf(&myval) aufgerufen.
Dies hat leier nicht funktionnert.
Kaiser K. schrieb: > Dies hat leier nicht funktionnert. Lass mich raten. Du hast immer noch "static" dran stehen. Warum? Weil du das irgendwo her kopiert hast?
Brummbär schrieb: > brainfuck Naja... Damit kann man nur beginnen, wenn einem schon ein paar Streusel auf dem Kuchen fehlen.
Dr. Sommer schrieb: > Lass mich raten. Du hast immer noch "static" dran stehen. Warum? Weil du > das irgendwo her kopiert hast? static habe ich nicht mehr dran stehen. aber es funktioniert sowohl mit static als auch ohne. das einzige was mir gefehlt hat ist in header struct tval zu schreiben....
Kaiser K. schrieb: > aber es funktioniert sowohl mit static als auch ohne. Kaum. Mit static bekommst du eine undefined reference Fehler Meldung, es sei denn der Aufruf steht in der selben Datei; dann wäre aber der Header komplett unnötig.
Kaiser K. schrieb: > das einzige was mir gefehlt hat ist in header struct tval zu > schreiben.... Dann lass auchich raten: Du hast nur eine C-datei, in der alle anderen include sind? Das ist nicht schlimm, machen viele anfangs, aber für größere Projekte nicht gut (und nicht gewollt) Deshalb kannst Du auch keinen Sinn in der Beschreibung von static erkennen? Du hast keine Warnungen eingeschaltet, weil es so viele sind? Oder ignorierst sie? Du hast keine Referenz zur hand, wo die Fehler des compilers erklärt werden (die gibt's aber). Das ist alles ok, wir haben auch so angefangen.
W.S. schrieb: > Das spart einem das Suchen, ob das nun was Externes oder bloß ne > Vorwärtsdeklaration in derselben Quelle ist W.S. schrieb: > Stimmt so nicht ganz. Wenn sie nicht explizit als static deklariert > wurde, kann man immer noch mitextern void val_printf(struct tval *); > > drauf zugreifen. > > C hat eben kein wirklich sauberes Modulkonzept, das muß man leider > hinnehmen. Hier beschwerst Du dich über das zu laxe Modulkonzept, ... Und oben hast Du extra einen Mechanismus, um das Unterlaufen zu erkennen. Und dann auch noch alles irgendwie anders als normal: Normal ist: - Funktionen in Header ohne extern, allein schon um es leichter von Daten zu unterscheiden. - in einer C-datei vorwärts nur mit static. - extern in einer C-Datei wenn, dann nur als Heck.egal ob bei Funktionen mit oder ohne extern. - und natürlich Warnungen, wenn globale Funktionen oder Daten nicht auch in einem Header stehen. .
Arduino Fanboy D. schrieb: > Gibts irgendeine Programmiersprachen, welche einen nicht bekloppt > macht...? Ja. Jene, die man nur verwendet, wenn man schon bekloppt ist.
Kaiser K. schrieb: > Dies hat leier nicht funktionnert. Fangen wir mal ganz klassisch an. Was hast du gemacht? Code, bitte. Was ist passiert? Was hätte deiner Meinung nach passieren sollen?
Kaiser K. schrieb: > Dr. Sommer schrieb: > >> Noch einmal die Frage: >> Warum eine "static" Funktion im Header deklarieren? Was soll das >> bezwecken? > > also ohne diese Funktion zu deklarieren bekomme ich als fehlermeldung : > undefined reference to 'val_printf' Die Frage war nicht, warum es deklariert ist, sondern warum static und gleichzeitig in einem Header. Das ergibt keinen Sinn. In einem Header steht die Deklaration, weil man die Funktion auch von einer anderen Übersetzungseinheit aus aufrufen können will. Static schreibt man davor, weil man das nicht will. Die Kombination aus beiden ist also unsinnig. W.S. schrieb: > Rufus Τ. F. schrieb: >> In C ist extern bei Funktionsprototypen das implizite Gegenteil von >> static und kann daher immer wegfallen. > > Kann aber MUSS aber nicht. Man kann es auch hinschreiben, aber es macht keinerlei Unterschied für das Programm. > Aus Gründen der Einheitlichkeit, auch der visuellen Einheitlichkeit > kommt bei mir nicht nur bei externen Daten, sondern auch bei externen > Funktionen das extern dran. Das spart einem das Suchen, ob das nun was > Externes oder bloß ne Vorwärtsdeklaration in derselben Quelle ist. Bei einer Vorwärtsdeklaration in der selben Quelle schreibt man eh static davor. Und eine Vorwärtsdeklaration externer Funktionen gehört nicht in die C-Datei, sondern in einen Header. Es besteht also keinerlei Gefahr, die Deklaration ohne das explizite extern als intern zu missverstehen. W.S. schrieb: > S. R. schrieb: >> Wenn sie >> nicht zur öffentlichen Schnittstelle gehört, dann ist sie static und >> steht nicht im Headerfile. > > Stimmt so nicht ganz. Wenn sie nicht explizit als static deklariert > wurde, kann man immer noch mit extern void val_printf(struct tval *); > drauf zugreifen. Deswegen macht man sie ja static, wenn man diesen Zugriff nicht will. > C hat eben kein wirklich sauberes Modulkonzept, das muß man leider > hinnehmen. Hä? static unterbindet die Zugriffsmöglichkeiten von außen und hilft nicht nur gegen versehentliche Zugriffe, sondern sogar gegen mutwillige Sabotage. Da gibt's also nichts hinzunehmen. Man muss es lediglich richtig machen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.