Hallo, habe mal eine Frage. Wenn ich im AVR-Studio in C eine Funktion aus einer Funktion aufrufe, die von der Main-Funktion aufgerufen wurde, erhalte ich beim Compilieren folgenden Hinweis (und danach noch ein paar andere, die dazu gehören): >>warning: implicit declaration of function 'y' Hier noch der schematische Aufbau: >int main(void){...} --> void x(){...} --> void y(){...} Bei built selber gibt keine weiteren Fehlermeldungen und der Controller funktioniert nach dem Flashen, wie er soll. Mich würde trotzdem interessieren, warum hier die Warnung erscheint? Außerdem würde mich interessieren, ob man Funktionen grundsätzlich mit "return" beenden sollte oder ob es prinzipiel egal ist?
Nachtrag, es soll natürlich heißen: Bei built selber gibt es keine weiteren Fehlermeldungen und der Controller funktioniert nach dem Flashen, wie er soll.
Die Warnung meint, das Du eine Funktion aufrufst, die an der Stelle des Aufrufs weder deklariert noch definiert wurde.
fragendermensch schrieb: > Hallo, > > habe mal eine Frage. > > Wenn ich im AVR-Studio in C eine Funktion aus einer Funktion aufrufe, > die von der Main-Funktion aufgerufen wurde, erhalte ich beim Compilieren > folgenden Hinweis (und danach noch ein paar andere, die dazu gehören): > >>>warning: implicit declaration of function 'y' "implicit declaration" bedeutet immer, dass eine Funktion benutzt wurde (aufgerufen wurde), noch ehe der COmpiler die Funktion selber, entweder als Funktions-Definition oder als Protoyp) zu Gesicht bekommen hat. Das ist also eine reine Frage der Reihenfolge der Funktionen in deinem File, bzw. ob du Prototypen hast oder nicht. Lies dein C-File von oben nach unten durch und überleg dir was du machen musst, damit beim Durchlesen des Codes es nie zu der Situation kommt, dass du eine Funktion aufrufen willst, noch ehe die Funktion deklariert ist.
> Mich würde trotzdem interessieren, warum hier die Warnung erscheint? Weil der Compiler dann Standard-Annahmen treffen muss. Die können richtig sein, können aber auch falsch sein. > Außerdem würde mich interessieren, ob man Funktionen grundsätzlich > mit "return" beenden sollte oder ob es prinzipiel egal ist? falsche Frage. Die richtige Frage lautet: wann brauche ich auf jeden Fall ein return?
Grundsätzlich sollte man alle Warnungen erst nehmen und beseitigen. Es gibt nur einige wenige Fälle wo das nicht möglich ist, aber die sind für Anfänger in der Regel unwichtig. >Außerdem würde mich interessieren, ob man Funktionen grundsätzlich mit >"return" beenden sollte oder ob es prinzipiel egal ist? Das kommt auf die Funktion an. Wenn sie einen Rückgabewert hat, dann muss ein return mit einem Ausdruck enthalten sein. Wenn der Rückgabewert void ist, dann kannst Du das return weglassen. Allerdings wird das teilweise als schlechter Stil betrachtet.
Einer ist hier überflüssig. Dann gucke ich jetzt Simpsons.
In der Datei, die die main enthält, mache ich es immer so, dass ich die Funktionsprototypen vor die main schreibe, aber die Funktionen selber dahinter.
1 | void x(); |
2 | void y(); |
3 | |
4 | int main(){...} |
5 | |
6 | void x(){...} |
7 | void y(){...} |
Dann kennt der Compiler die Funktionen und kann sie richtig benutzen, aber bis auf eine kurze Liste mit Funktionsprototypen steht die main ganz oben. So sieht man auf den ersten Blick die main und muss nur suchen, wenn man sich eine Funktion genauer ansehen will. Hmm schrieb: > Dann gucke ich jetzt Simpsons. Auf ProSieben kommen die etwa um zehn nach sieben.
Karl Heinz Buchegger schrieb: > Lies dein C-File von oben nach unten durch und überleg dir was du machen > musst, damit beim Durchlesen des Codes es nie zu der Situation kommt, > dass du eine Funktion aufrufen willst, noch ehe die Funktion deklariert > ist. Hallo, herzlichen Dank für die schnellen und vielen Antworten!!! Habe jetzt die Reihenfolge der Funktionen im Programmfile geändert, nun wird keine Warnung mehr angezeigt. Was genau versteht man unter einem Funktionsprototypen? Viele Grüße
Dussel schrieb: ... > > int main(){...} > > void x(){...} > void y(){...}Dann kennt der Compiler die Funktionen und kann sie richtig benutzen, > aber bis auf eine kurze Liste mit Funktionsprototypen steht die main > ganz oben. So sieht man auf den ersten Blick die main und muss nur > suchen, wenn man sich eine Funktion genauer ansehen will. Super, das mache ich beim nächsten mal auch so, Danke! Bisher landet die Main-Funktion bei mir immer gaaaanz unten :-)
Hmm schrieb: > Einer ist hier überflüssig. Dann gucke ich jetzt Simpsons. auf u-tube kann man die auch gucken
fragendermensch schrieb: > Was genau versteht man unter einem Funktionsprototypen? 2 Dinge. Das erste bedeutet, dass du ganz dringend ein C-Buch brauchst Das zweite: Den Funktionskopf, in dem man festlegt, wie die Funktion nach aussen aussieht. hast du eine Funktion double CalcMwst( double Preis ) { return 0.2 * Preis; } dann ist double CalcMwst( double ); der zugehörige Protoyp. Alles was ein Aufrufer von der Funktion wissen muss, um sie korrekt benutzen zu können. Und das ist * wie heißt die Funktion * welche und wieviele Argumente nimmt sie? Welche Datentypen haben die Argument? * welchen Returntyp hat die Funktion Aus praktischen Gründen ist es sinnvoll, die Namen der Argumente mit in den Protoypen aufzunehmen double CalcMwst( double Preis );
Karl Heinz Buchegger schrieb: > ... der zugehörige Protoyp. Alles was ein Aufrufer von der Funktion wissen > muss, um sie korrekt benutzen zu können. Und das ist > * wie heißt die Funktion > * welche und wieviele Argumente nimmt sie? > Welche Datentypen haben die Argument? > * welchen Returntyp hat die Funktion > > Aus praktischen Gründen ist es sinnvoll, die Namen der Argumente mit in > den Protoypen aufzunehmen > double CalcMwst( double Preis ); Danke für die Erklärung! Im Grunde ist es von der Form her (ähnlich) wie der Funktionsaufruf selber, nur, dass man es "frei" vor die Main- und andere Funktionen schreiben kann!?! Karl Heinz Buchegger schrieb: > Das erste bedeutet, dass du ganz dringend ein C-Buch brauchst Wird beherzigt!
fragendermensch schrieb: > Danke für die Erklärung! Im Grunde ist es von der Form her (ähnlich) wie > der Funktionsaufruf selber, Nicht wie der Funktions-AUFRUF sondern wie die Funktion selber. Nur eben ohne die Implementierung. Der Prototyp enthält alles was man wissen muss, um zu entscheiden, ob ein Aufruf
1 | int main() |
2 | {
|
3 | double i, j = 5; |
4 | |
5 | i = CalcMwst( j, 8 ); |
6 | }
|
korrekt sein kann (der hier kann nicht korrekt sein, weil die Funktion ja keine 2 Argumente nimmt), bzw. welche Umwandlungen automatisch vorgenommen werden müssen (sofern dies möglich ist)
1 | int main() |
2 | {
|
3 | int j; |
4 | |
5 | j = CalcMwst( 6 ); |
6 | }
|
der Integer 6 muss zum Aufruf der Funktion in einen double gewandelt werden und das Funktionsergebnis muss von einem double zu einem int gewandelt werden. Damit man das erkennen kann, reicht es völlig aus, wenn man ...
1 | double CalcMwst( double ); |
... weiß - vulgo den Funktionsprotoypen. Und mehr als dieses Wissen benötigt der Compiler nicht, um den Aufruf auf Korrektheit zu prüfen und korrekt durchzuführen.
Wenigstens haben die Österreicher noch nicht die deutsche Unsitte übernommen, nach jedem halben Satz Klopapier und Achselschweiss zu verkaufen. Das und Almdudlder und Salzburger Nockerln läßt mich manchmal von der Auswanderung nach Österreich träumen.
Korrektur. Die machen das jetzt auch. Mist. Naja. War sowieso Off-Topic. Sorry.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.