conflicting types for 'fonction'

OP #5545438
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:
  }
}
Gast
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.
Beitrag #5545454 wurde von einem Moderator gelöscht.
OP
.                                                . 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
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é
Gast
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
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_ */
Gast
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
Gast
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
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
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
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
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
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
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
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.
Gast
> 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
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
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.
Gast
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
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.

.
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

Eine eigene Frage? Dieser Thread ist über 8 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.