Forum: Mikrocontroller und Digitale Elektronik conflicting types for 'fonction'


von Kaiser K. (kingkong_18)


Lesenswert?

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:
  }
}

von Dr. Sommer (Gast)


Lesenswert?

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.

von Xeraniad X. (xeraniad)


Lesenswert?

Ohne Gewähr: muss evtl. im .h vor der Deklaration noch "extern" stehen.

von . . (Gast)


Lesenswert?

Da sind sicher noch andere Fehlermeldungen.
Weiß denn der Header wo "struct tval" definiert ist?

Beitrag #5545454 wurde von einem Moderator gelöscht.
von Kaiser K. (kingkong_18)


Lesenswert?

.                                                . 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

von René H. (Gast)


Lesenswert?

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é

von Domi (Gast)


Lesenswert?

lass mal das struct weg

static void val_printf(tval *message_Id)

von Dr. Sommer (Gast)


Lesenswert?

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).

von 50c (Gast)


Lesenswert?

Dr. Sommer schrieb:
> "extern" an Funktionen ist
> übrigens komplett überflüssig (hat keinerlei Wirkung)

...in diesem speziellen Fall oder allgemein?

von Kaiser K. (kingkong_18)


Lesenswert?

Domi schrieb:
> lass mal das struct weg
>
> static void val_printf(tval *message_Id)

funktionniert leider nicht

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

50c schrieb:
> ...in diesem speziellen Fall oder allgemein?

In C ist extern bei Funktionsprototypen das implizite Gegenteil von 
static und kann daher immer wegfallen.

von Kaiser K. (kingkong_18)


Lesenswert?

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_ */

von Dr. Sommer (Gast)


Lesenswert?

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?

von (prx) A. K. (prx)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von 50c (Gast)


Lesenswert?

...du musst den struct tval als Typ definieren (in der Header-Datei) und 
dann mit diesem Typ bei den Deklarationen arbeiten

von Mr. OCD (Gast)


Lesenswert?

tval.w ist nicht und ob in der Union 2 y möglich sind?
"w" wird auch nie geprinted.

von (prx) A. K. (prx)


Lesenswert?

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.

von Kaiser K. (kingkong_18)


Lesenswert?

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'

von Kaiser K. (kingkong_18)


Lesenswert?

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

von Einer K. (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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".

von Dirk K. (merciless)


Lesenswert?

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

von Harry L. (mysth)


Lesenswert?

static-forward-Deklarationen gehören in den Kopf der C-Datei und NICHT 
in den Header!

Lesen, was Dr. Sommer schreibt!

von Kaiser K. (kingkong_18)


Lesenswert?

Dr. Sommer schrieb:

> Kann nicht sein. Höchstens wenn du sie nicht definierst.

definieren meinte ich sorry

von Dr. Sommer (Gast)


Lesenswert?

Kaiser K. schrieb:
> definieren meinte ich sorry

Ja, definieren musst du sie natürlich. Aber warum deklarierst du sie 
in der Header-Datei?

von S. R. (svenska)


Lesenswert?

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.

von Harry L. (mysth)


Lesenswert?

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.
von W.S. (Gast)


Lesenswert?

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.

von Harry L. (mysth)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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...

von W.S. (Gast)


Lesenswert?

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.

von W.S. (Gast)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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.

von Harry L. (mysth)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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

von Harry L. (mysth)


Lesenswert?

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.
von Einer K. (Gast)


Lesenswert?

Gibts irgendeine Programmiersprachen, welche einen nicht bekloppt 
macht...?

Jetzt mal Lisp und Forth ausgenommen, denn die sind voll normal.

von Programmiersprachentheaterintendant (Gast)


Lesenswert?

> 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

von Brummbär (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Gibts irgendeine Programmiersprachen, welche einen nicht bekloppt
> macht...?

brainfuck

von Kaiser K. (kingkong_18)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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?

von Einer K. (Gast)


Lesenswert?

Brummbär schrieb:
> brainfuck
Naja...

Damit kann man nur beginnen, wenn einem schon ein paar Streusel auf dem 
Kuchen fehlen.

von Kaiser K. (kingkong_18)


Lesenswert?

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....

von Dr. Sommer (Gast)


Lesenswert?

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.

von A. S. (Gast)


Lesenswert?

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.

von A. S. (Gast)


Lesenswert?

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.

.

von (prx) A. K. (prx)


Lesenswert?

Arduino Fanboy D. schrieb:
> Gibts irgendeine Programmiersprachen, welche einen nicht bekloppt
> macht...?

Ja. Jene, die man nur verwendet, wenn man schon bekloppt ist.

von S. R. (svenska)


Lesenswert?

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?

von Rolf M. (rmagnus)


Lesenswert?

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
Noch kein Account? Hier anmelden.