mikrocontroller.net

Forum: Compiler & IDEs warning: function declaration isn't a prototype


Autor: sammy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beim Kompilieren kriege ich die Meldung:
warning: function declaration isn't a prototype

Die Betreffenden Zeilen sehen wie folgt aus:
static void led_schiebe_hochzaehlen()
{
    sbi(PORTB,1);// Schieberegister hochzaehlen
    cbi(PORTB,1);
    cbi(PORTB,0);
}



Was ist daran falsch??

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daß es keine Prototypendeklaration ist. ;-)

static void led_schiebe_hochzaehlen(void)
{
...
}

(Bei C++ wäre das anders, dort ist eine leere Parameterliste mit
`void' identisch.)

Autor: sammy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay, jetzt meckert er nicht mehr.
Danke.

Autor: Simon King (simonking)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag!

Ich weiß, dass "warning: function declaration isn't a prototype" 
normalerweise bedeutet, dass man
 int function_name() 
 statt
 int function_name(void) 
 geschrieben hat.

Aber ich bekomme die Warnung
  mtx2.2.3/src/meataxe.h:537: Warnung: Funktionsdeklaration ist kein 
Prototyp

Und in Zeile 537 von meataxe.h steht:
 int errhandler(int errno, char *errfile, int errline);

Was ist denn an dieser Zeile falsch?

Viele Grüße
     Simon

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon King schrieb:

> Und in Zeile 537 von meataxe.h steht:
>
 int errhandler(int errno, char *errfile, int errline);
> 
>
> Was ist denn an dieser Zeile falsch?

So erst mal gar nichts.
Was ist denn mit der Zeile davor?

Autor: Simon King (simonking)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Simon King schrieb:
>> Was ist denn an dieser Zeile falsch?
>
> So erst mal gar nichts.
> Was ist denn mit der Zeile davor?

Der Kontext (Zeilen 533-539) ist
extern int mtxerrno;
extern int mtxerraction;
void mtxerror(char *text);
void errexit(int code, char *text);
int errhandler(int errno, char *errfile, int errline);
int Message(FILE *f, const char *fmt, ...);
int ErrorExit(const char *fmt, ...);

Nebenfragen: Was ist denn daran schlimm, wenn irgend etwas nicht als 
Prototyp definiert ist? Kann es dadurch zu Fehlern kommen?

Ich habe zumindest den Eindruck, dass das Compilieren ewig lange dauert, 
wenn es diese Warnung gibt; stimmt mein Eindruck?

Viele Grüße
   Simon

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon King schrieb:

> Nebenfragen: Was ist denn daran schlimm, wenn irgend etwas nicht als
> Prototyp definiert ist? Kann es dadurch zu Fehlern kommen?

Beispielsweise dann:

file1.c:
  void f(long x) { ... };

file2.c:
  extern void f();
  f(1);

Hier wird die "1" als "int" übergeben aber als "long" verarbeitet.

Funktionsdeklarationen mit leerem () sind antikes K&R C, nur noch aus 
historischen Gründen drin.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon King schrieb:

> Der Kontext (Zeilen 533-539) ist
>
> extern int mtxerrno;
> extern int mtxerraction;
> void mtxerror(char *text);
> void errexit(int code, char *text);
> int errhandler(int errno, char *errfile, int errline);
> int Message(FILE *f, const char *fmt, ...);
> int ErrorExit(const char *fmt, ...);
> 

Ich kann hier nichts erkennen, was diese Warnung hervorbringen könnte. 
Eventuell könnten ihn die ... stören, aber auch das sollte eigentlich 
kein Problem sein. Bist du sicher, dass die Zeilennummern stimmen? 
Manchmal hat der Compiler eine etwas andere Vorstellung von der 
Nummerierung als der Editor. Sicher gehen kannst du, indem du mutwillig 
einen Fehler in das Header File einbaust, und nachsiehst, welche 
Zeilennummer beim Fehler ausgegeben wird.

> Nebenfragen: Was ist denn daran schlimm, wenn irgend etwas nicht als
> Prototyp definiert ist? Kann es dadurch zu Fehlern kommen?

Ja klar.
Der Compiler hat dann keine Möglichkeit mehr die Argumente, die du an 
eine Funktion übergibst, auf Korrektheit zu prüfen und muss alles 
akzeptieren.

> Ich habe zumindest den Eindruck, dass das Compilieren ewig lange dauert,
> wenn es diese Warnung gibt; stimmt mein Eindruck?

Kann ich mir nicht vorstellen.
Das sollte eigentlich ziemlich egal sein.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> Ich kann hier nichts erkennen, was diese Warnung hervorbringen könnte.

Man könnte sich mal die Ausgabe des Präprozessors angucken (Option
-E).  Was ich mir beispielsweise vorstellen könnte ist, dass da
irgendwo was davor steht wie
#define errno __get_errno()

Aus diesem Grunde schreibt man Funktionsprototypen in (öffentlichen)
Headerdateien in der Regel ohne Parameternamen, also nur die Typen
der Parameter (denn nur die sind für den Compiler hier interessant).
Damit würde obiger Ausschnitt dann so aussehen:
void mtxerror(char *);
void errexit(int, char *);
int errhandler(int, char *, int);
int Message(FILE *, const char *, ...);
int ErrorExit(const char *, ...);

Autor: Simon King (simonking)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Ich kann hier nichts erkennen, was diese Warnung hervorbringen könnte.
> Eventuell könnten ihn die ... stören, aber auch das sollte eigentlich
> kein Problem sein. Bist du sicher, dass die Zeilennummern stimmen?

Ich habe an den Anfang der Zeile testhalber einen Fehler geschrieben, 
und es ist tatsächlich Zeile 537.

Man könnte sich ja auf den Standpunkt stellen, dass eine Warnung egal 
ist, solange es am Ende funktioniert (und das tut es). meataxe.h ist 
außerdem nicht von mir. Allerdings arbeite ich damit und habe auch schon 
was modifiziert.

Ich habe den Header angehängt, falls jemand zu viel Zeit hat :)
Falls nicht, ist es auch nicht schlimm: Ich bin neugierig, aber da das 
Programm am Ende funktioniert, ist das Problem für mich nicht dringend.

Viele Grüße
    Simon

Autor: Simon King (simonking)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch schrieb:
...
> Was ich mir beispielsweise vorstellen könnte ist, dass da
> irgendwo was davor steht wie
>
>
> #define errno __get_errno()
> 

Das steht zumindest nicht in diesem Header, und ich habe es auch 
woanders nicht gefunden. Aber trotzdem scheint sowas der Grund gewesen 
zu sein. Ich ließ die Parameternamen weg, und die Warnung verschwand. 
Mit der Compilierzeit hat es aber wohl wirklich nichts zu tun.

Also, vielen Dank allerseits!
Viele Grüße
    Simon

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon King schrieb:

> Das steht zumindest nicht in diesem Header, und ich habe es auch
> woanders nicht gefunden. Aber trotzdem scheint sowas der Grund gewesen
> zu sein. Ich ließ die Parameternamen weg, und die Warnung verschwand.

gcc -E hätte dir zumindest verraten, was der Compiler denn wirklich
gesehen hat.  Wo das #define dann steht, musst du in deinen Dateien
allerdings trotzdem noch selbst suchen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch schrieb:
> -E).  Was ich mir beispielsweise vorstellen könnte ist, dass da
> irgendwo was davor steht wie
>
>
> #define errno __get_errno()
> 

Könnte durchaus sein.

> Aus diesem Grunde schreibt man Funktionsprototypen in (öffentlichen)
> Headerdateien in der Regel ohne Parameternamen, also nur die Typen
> der Parameter (denn nur die sind für den Compiler hier interessant).

Ehrlich gesagt hasse ich das wie die Pest :-)
Die Argumentnamen helfen mir auch oft, bei der Ergründung was denn eine 
Funktion macht und wie und welche Parameter sie erwartet.
Allerdings bin ich noch nie in obiges Problem gekommen, denn einen 
Argumentnamen 'errno' würde es bei mir sowieso nie geben. Bin ein Fan 
von CamelCase :-) Ich find das einfach leichter zu lesen und schneller 
verständlich, wenn mir ein Grossbuchstabe das nächste 'Wort' im 
Variablennamen anzeigt.
extern int mtxErrNo;
extern int mtxErrAction;
void MtxError( const char* text );
void ErrExit( int code, const char* text );
int  ErrHandler( int errNo, const char* errFile, int errLine );
int  Message( FILE* f, const char* fmt, ...);
int  ErrorExit( const char* fmt, ...);

> Man könnte sich ja auf den Standpunkt stellen, dass eine Warnung
> egal ist, solange es am Ende funktioniert (und das tut es).

Ich denke du hast die richtige Grundeinstellung: Eine Warnung sollte nie 
egal sein, sondern man sollte ihr auf den Grund gehen und den Code so 
verändern, dass die Warnung verschwindet. In vielen Warnungen steckt ein 
potentielles und oft genug auch ein tatsächliches Problem. Lässt man den 
Compiler 'einen guten Mann sein' und ignoriert Warnungen, dann gehen die 
wirklich wichtigen Warnungen in der Flut der restlichen Warnungen unter.

In vielen Firmen gilt die Devise: Code muss ohne Warnungen auf einer 
bestimmten, nicht trivialen, Warnstufe compilieren.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon King schrieb:
> Jörg Wunsch schrieb:
> ...
>> Was ich mir beispielsweise vorstellen könnte ist, dass da
>> irgendwo was davor steht wie
>>
>>
>> #define errno __get_errno()
>> 
>
> Das steht zumindest nicht in diesem Header, und ich habe es auch
> woanders nicht gefunden.

errno ist eine globale 'Variable' aus der Standard Library.
Wird also wohl über irgendeinen Standard Header ins System reinkommen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

>> Aus diesem Grunde schreibt man Funktionsprototypen in (öffentlichen)
>> Headerdateien in der Regel ohne Parameternamen, also nur die Typen
>> der Parameter (denn nur die sind für den Compiler hier interessant).
>
> Ehrlich gesagt hasse ich das wie die Pest :-)

> Die Argumentnamen helfen mir auch oft, bei der Ergründung was denn eine
> Funktion macht und wie und welche Parameter sie erwartet.

Dafür sollte es ein Manual geben, das das erklärt.  Normalerweise
hat das Manual aber nicht den Dateinamenssuffix .h ... ;-)

Autor: Simon King (simonking)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Simon King schrieb:
>> Jörg Wunsch schrieb:
>> ...
>>> Was ich mir beispielsweise vorstellen könnte ist, dass da
>>> irgendwo was davor steht wie
>>>
>>>
>>> #define errno __get_errno()
>>> 
>>
>> Das steht zumindest nicht in diesem Header, und ich habe es auch
>> woanders nicht gefunden.
>
> errno ist eine globale 'Variable' aus der Standard Library.
> Wird also wohl über irgendeinen Standard Header ins System reinkommen.

Das ist es vermutlich. Am Anfang von meataxe.h steht nämlich
#include <sys/types.h>
#include <stdio.h>

Also, danke nochmal
     Simon

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.