conflicting types for 'fonction'

OP #5545438
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:
  }
}
Beitrag #5545454 wurde von einem Moderator gelöscht.
OP #5545462
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
Gast #5545490
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).
OP #5545517
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_ */
#5545526
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
Gast #5545556
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".
#5545639
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.
Beitrag #5545657 wurde von einem Moderator gelöscht.
Gast #5545658
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.
Gast #5545665
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...
Gast #5545668
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.
Gast #5545673
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.
Gast #5545690
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.
Persönliche Seite #5545712
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
#5545714
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.
Gast #5545926
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
OP #5546025
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.
Gast #5546087
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.
Gast #5546114
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.

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren