Forum: Compiler & IDEs AVR-GCC meldet implicit declaration


von Ralf (Gast)


Lesenswert?

Hallo ihr Experten,

ich bekomme beim kompilieren immer eine "implicit declaration" Warnung. 
Das Programm läuft zwar trotzdem korrekt aber ich wüsste gerne warum das 
falsch ist.

Konkret geht es um den Aufruf einer Funktion innerhalb einer If 
Abfragefunktion. Dort wird aufgerufen:

void tasterabfrage(void)
{
if (taster ==1)
{
timereset();
}
}


Die aufzurufende Funktion selbst ist folgendermaßen deklariert:

void timereset(void)
{
variable1=variable2;
}

: Verschoben durch Admin
von Curby23523 N. (Gast)


Lesenswert?

C Grundlagen. Schiebe mal die Funktion void timereset(void) vor die 
tasterabfrage.

Alternativ kannst du am Anfang deiner C-Datei auch schreiben:
1
void timereset(void);

Warum, dazu lese dich mal in C Grundlagen ein.

von Oliver S. (oliverso)


Lesenswert?

Die Reihenfolge ist nicht ganz unwichtig. Die Deklaration muß vor dem 
ersten Aufruf stehen, ansonsten kennt der Compiler die dort noch nicht.

Daher schreibt man die Deklaration an den Anfang.
1
void timereset(void);

Oliver

von fop (Gast)


Lesenswert?

Hi,
die Funktion ist aber erst definiert, nachdem Du sie schonmal genutzt 
hast.
Deshalb gibt es bei der Benutzung eine Warnung und der Compiler macht 
wüste Spekulationen über Parameter und Rückgabewert sowie deren 
Datentypen.

Also zunächst alle Funktionen deklarieren :
1
void tasterabfrage(void);
2
void timereset(void);

So etwas kann gerne auch in einer Header-Datei geschehen, wenn die 
Funktionen in mehreren Quelltexten genutzt werden.

Dann die Funktionen nach und nach definieren :
1
void tasterabfrage(void)
2
{
3
...
4
}
5
6
void timereset(void)
7
{
8
...
9
}

Wenn Du es ganz fein säuberlich machen willst, achtest Du darauf, dass 
es nur genau eine Deklaration für jede Funktion gibt (für Variablen gilt 
das ähnlich).
Sprich, wird die Funktion in einer .c - Datei verwendet, steht die 
Deklaration vor den Funktionsdefinitionen in dieser .c - Datei. Und 
damit sich auch kein anderer Quelltext dran vergeht, sind die Funktionen 
als static gekennzeichnet.
Brauchst Du die Funktion in mehreren Quelltexten, so schreibt man die 
Deklaration einmal in einer .h-Datei. Wobei auch die .c-Datei, die die 
Funktion definiert, jene .h-Datei einbindet.
Das stellt sicher, dass sich alle einig sind, welchen Typ Rückgabewert 
und Parameter haben.
Weil merke : wenn es mehrere Deklarationen gibt, könnten sie 
unterschiedlich sein. Und weil laut Murphy alles schief geht, was schief 
gehen kann, werden sie irgendwann unterschiedliche Parametertypen haben, 
was zu witzigen, aber schlecht zu behebenden Fehlfunktionen führt.

Und bitte jetzt nicht damit kommen, dass das bei Arduino auch anders 
geht. Ja, die haben einen Parser eingebaut, der zu allen Funktionen 
Deklarationen erstellt und automatisch dem Compiler zur Verfügung 
stellt, so dass sich Programmieranfänger damit nicht herumplagen müssen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ralf schrieb:
> ich bekomme beim kompilieren immer eine "implicit declaration" Warnung.
> Das Programm läuft zwar trotzdem korrekt aber ich wüsste gerne warum das
> falsch ist.

Es gibt Programme, die ohne (korrekte) Prototypen nicht korrekt 
übersetzt werden (können).  Um solche Fehler zu vermeiden, warnt gcc — 
und zwar auch dann, wenn der erzeugte Code das tut, was er soll.

Daher wird für avr-gcc empfohlen, auch folgende Schalter bzw. 
Diagnostics zu aktivieren:

-Wmissing-prototypes
-Wstrict-prototypes

Weil es wie gesagt für manche ABIs / Architekturen sein kann (z.B. für 
avr) dass ohne Prototypen kein funktionales Programm zu erhalten ist, 
sollten man jedoch die strikteren

-Werror=missing-prototypes
-Werror=strict-prototypes

verwenden.

von HildeK (Gast)


Lesenswert?

Wenn die Funktionen in einer Datei stehen und man keine Deklarationen 
macht/machen will, dann muss die Funktion, die zuerst in einer Routine 
benutzt wird, auch zu oberst im File kommen.
Weil das umständlich ist, den Code darauf zu prüfen, macht man die 
genannten Deklarationen.

von Tim (Gast)


Lesenswert?

Hi Johann, danke für den Hinweis. Gibt es noch andere Empfehlungen, 
welche Warn-Parameter man aktivieren sollte, um ähnliche Probleme 
schnell aufzudecken?

Ich mache immer -W -Wall -Wextra -Wstrict-overflow -Waddr-space-convert. 
Aber das scheint ja nicht der Weisheit letzter Schluss zu sein. 
Zumindest hat dein Hinweis bei einem meiner Quelltexte ein kleines 
Problem zu Tage gefördert.

von S. R. (svenska)


Lesenswert?

Ein -Wall sollte das -W ersetzen. :-)
Ansonsten ist vielleicht noch -pedantic hilfreich.

von Tim (Gast)


Lesenswert?

-pedantic spuckt halt viel wirres Zeug aus, das nicht wirklich weiter 
hilft. Alleine die ganzen Warnungen zu Binärkonstanten (die ich zu 
Hunderten benutze) überfluten den Bildschirm völlig.

von S. R. (svenska)


Lesenswert?

Der Sinn von Warnungen ist es, dich auf Dinge hinzuweisen, die du anders 
besser machen könntest. Auch wenn ein pedantischer Compiler meist nur 
auf Prinzipien rumreitet, so ganz unrecht hat er meist nicht. :-)

Es gibt in C keine Binärkonstanten, also ist dein Code schonmal kein C. 
Egal, wie offensichtlich es ist, was du hinschreibst. ;-)

von Tim (Gast)


Lesenswert?

Fakt ist, dass Binärkonstanten aber korrekt implementiert sind und 
funktionieren und sicher auch nicht geplant ist, dieses jemals wieder 
aus dem gcc zu entfernen. Diese Warnung ist völlig praxisfern und mutet 
steinzeitlich an. Genauso die Warnung vor doppelten Semikola.
Wer Binärkonstanten benutzt, tut dies aus gutem Grund. Meinst du, der 
Code wird lesbarer und besser, wenn ich es als Hex oder Dez schreibe und 
beim Verstehen des Codes jedesmal im Kopf rechnen darf!?

Ist aber auch egal. -pedantic führt keine anderen hilfreichen Meldungen 
zutage, so wie es z.B. -Wmissing-prototypes tat. Meine Frage war, ob es 
noch mehr praxistaugliche Warn-Schalter gibt, die man auch sinnvoll 
verwenden sollte.

von MaWin O. (Gast)


Lesenswert?

Tim schrieb:
> Meinst du, der
> Code wird lesbarer und besser, wenn ich es als Hex oder Dez schreibe und
> beim Verstehen des Codes jedesmal im Kopf rechnen darf!?

Der Code wird besser, wenn du den Compiler rechnen lässt und Namen für 
Konstanten vergibst.
Binärkonstanten sind überflüssig.

von S. R. (svenska)


Lesenswert?

Tim schrieb:
> Fakt ist, dass Binärkonstanten aber korrekt implementiert sind und
> funktionieren und sicher auch nicht geplant ist, dieses jemals wieder
> aus dem gcc zu entfernen.

Auf allen Architekturen? Das war m.W. lange eine Spezialität vom 
AVR-GCC.

Tim schrieb:
> Genauso die Warnung vor doppelten Semikola.

Sowas nehme ich - wie auch Leerzeichen am Ende der Zeile - als 
oberflächliches Maß für die Qualität eines Quelltextes. Im Sinne von: 
Wie ordentlich hat der Autor gearbeitet.

Einen Text bewerte ich auch nach der Rechtschreibfehlerdichte. Wem die 
Form egal ist, dem kann auch der Inhalt nicht sehr wichtig sein.

Tim schrieb:
> Meinst du, der Code wird lesbarer und besser,
> wenn ich es als Hex oder Dez schreibe und
> beim Verstehen des Codes jedesmal im Kopf rechnen darf!?

Wenn du sinnvolle Namen benutzt, ja.
Auf einem 8-Bitter kann man Binärkonstanten noch sinnvoll einsetzen, auf 
einem 32-Bitter nicht.

Tim schrieb:
> Ist aber auch egal. -pedantic führt keine anderen hilfreichen Meldungen
> zutage, so wie es z.B. -Wmissing-prototypes tat.

"Hilfreich" ist aber deine persönliche Meinung. ;-)

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

S. R. schrieb:
> Der Sinn von Warnungen ist es, dich auf Dinge hinzuweisen, die du anders
> besser machen könntest.

Eigentlich ist der Sinn, auf Dinge hinzuweisen, die mit einer gewissen 
Wahrscheinlichkeit fehlerhaft sind. Die kann man dann nicht besser 
machen, sondern richtiger.

Oliver

von Rolf M. (rmagnus)


Lesenswert?

Tim schrieb:
> Fakt ist, dass Binärkonstanten aber korrekt implementiert sind und
> funktionieren und sicher auch nicht geplant ist, dieses jemals wieder
> aus dem gcc zu entfernen. Diese Warnung ist völlig praxisfern und mutet
> steinzeitlich an. Genauso die Warnung vor doppelten Semikola.

Das hat nichts mit "steinzeitlich" zu tun. Das Handbuch sagt explizit 
folgendes zu -pedantic:

"Issue all the warnings demanded by strict ISO C and ISO C++; reject all 
programs that use forbidden extensions, and some other programs that do 
not follow ISO C and ISO C++. For ISO C, follows the version of the ISO 
C standard specified by any -std option used."

Es ist also genau dafür da, bei allem zu warnen, das nicht strikt ISO-C 
ist, oder anders gesagt, bei Konstrukten, für die ISO C vorschreibt, 
dass der Compiler mindestens warnen muss.

> Ist aber auch egal. -pedantic führt keine anderen hilfreichen Meldungen
> zutage, so wie es z.B. -Wmissing-prototypes tat.

Wenn man nicht an ISO-C-Konformität interessiert ist, dann mag das sein.

von S. R. (svenska)


Lesenswert?

Oliver S. schrieb:
> Eigentlich ist der Sinn, auf Dinge hinzuweisen, die mit einer gewissen
> Wahrscheinlichkeit fehlerhaft sind.

Wenn du Dinge tust, die nicht dem C-Standard entsprechen, dann sind sie 
entsprechend des C-Standards ziemlich sicher fehlerhaft (d.h. 
implementation-defined oder undefined).

Falls dich das nicht interessiert, programmierst du kein C, sondern 
einen C-ähnlichen Dialekt des gcc auf einer bestimmten Architektur. 
Wieviel "avr-gcc" für dich akzeptabel ist, kannst nur du wissen. Ich 
habe dir "-pedantic" auch nur vorgeschlagen, eben aus diesem Grund.

von Oliver S. (oliverso)


Lesenswert?

S. R. schrieb:
> Wieviel "avr-gcc" für dich akzeptabel ist, kannst nur du wissen. Ich
> habe dir "-pedantic" auch nur vorgeschlagen, eben aus diesem Grund.

Ich bin vermutlich nicht das du, das du meinst, aber egal.

Oliver

von Jim M. (turboj)


Lesenswert?

Tim schrieb:
> Alleine die ganzen Warnungen zu Binärkonstanten (die ich zu
> Hunderten benutze) überfluten den Bildschirm völlig.

Macht der das auch wenn man Gnu Extensions über --std=gnu11 einschaltet? 
Kann aber sein, weil das IIRC nur auf AVR tut.

Hunterte Binärkonstanten sind aber auch eher schlechter Stil, da die 
IMHO fehlerträchtiger als Hex sind.

von S. R. (svenska)


Lesenswert?

Oliver S. schrieb:
> Ich bin vermutlich nicht das du, das du meinst, aber egal.

Stimmt, ich meinte Tim - also den, von dem die letzte Diskussion 
ausging. :-)

: Bearbeitet durch User
von Tim (Gast)


Lesenswert?

Ja, auch dann.

Die Binärkonstanten sind alles Sachen, wo man gleich erkennen sollte, 
welches Bit gesetzt ist oder nicht. Beispiel: Konfiguration von 
I2C-Geräten. Wenn ich da Hex oder Dez schreibe, kann ich das nicht 
sofort sehen.

Aber ist auch egal. Pedantic ist nicht für mich geeignet, da es keinen 
Informationsvorteil bringt. Aber eventuell hat ja noch einer einen 
Geheimtipp für andere Warnschalter.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Tim schrieb:
> wo man gleich erkennen sollte, welches Bit gesetzt ist oder nicht.

Dafür sind Binärkonstanten aber auch nicht hilfreich. Besser sind 
sprechende Namen der Bits bzw. der Bit-Werte, die dann mit OR 
kombiniert werden. So macht es der Rest der Welt.

Ansonsten ist der intellektuelle Sprung zu tatsächlich standardkonformen 
Hexadezimalkonstanten nun wirklich nicht gigantisch; man muss nur 16 
Bitkombinationen "lernen", um ein Nibble zu verstehen. Damit beschäftigt 
man sich mal 'ne Woche lang, dann kann man's für den Rest des Lebens und 
braucht keine Binärkonstanten. Die werden obendrein bei mehr als 8 Bit 
reichlich unübersichtlich, was man von Hexkonstanten erst jenseits der 
32 Bit sagen kann.

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.