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


von sammy (Gast)


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

von Jörg Wunsch (Gast)


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

von sammy (Gast)


Lesenswert?

Okay, jetzt meckert er nicht mehr.
Danke.

von Simon K. (simonking)


Lesenswert?

Guten Tag!

Ich weiß, dass "warning: function declaration isn't a prototype" 
normalerweise bedeutet, dass man
1
 int function_name()
 statt
1
 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:
1
 int errhandler(int errno, char *errfile, int errline);

Was ist denn an dieser Zeile falsch?

Viele Grüße
     Simon

von Karl H. (kbuchegg)


Lesenswert?

Simon King schrieb:

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

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

von Simon K. (simonking)


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
1
extern int mtxerrno;
2
extern int mtxerraction;
3
void mtxerror(char *text);
4
void errexit(int code, char *text);
5
int errhandler(int errno, char *errfile, int errline);
6
int Message(FILE *f, const char *fmt, ...);
7
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

von (prx) A. K. (prx)


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.

von Karl H. (kbuchegg)


Lesenswert?

Simon King schrieb:

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

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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
1
#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:
1
void mtxerror(char *);
2
void errexit(int, char *);
3
int errhandler(int, char *, int);
4
int Message(FILE *, const char *, ...);
5
int ErrorExit(const char *, ...);

von Simon K. (simonking)


Angehängte Dateien:

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

von Simon K. (simonking)


Lesenswert?

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

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Karl H. (kbuchegg)


Lesenswert?

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

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.
1
extern int mtxErrNo;
2
extern int mtxErrAction;
3
void MtxError( const char* text );
4
void ErrExit( int code, const char* text );
5
int  ErrHandler( int errNo, const char* errFile, int errLine );
6
int  Message( FILE* f, const char* fmt, ...);
7
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.

von Karl H. (kbuchegg)


Lesenswert?

Simon King schrieb:
> Jörg Wunsch schrieb:
> ...
>> Was ich mir beispielsweise vorstellen könnte ist, dass da
>> irgendwo was davor steht wie
>>
>>
1
>> #define errno __get_errno()
2
>>
>
> 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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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

von Simon K. (simonking)


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
>>>
>>>
1
>>> #define errno __get_errno()
2
>>>
>>
>> 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
1
#include <sys/types.h>
2
#include <stdio.h>

Also, danke nochmal
     Simon

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.