AVR-Studio: Funktion aus Funktion aufrufen: Warnung

Gast #3159166
Lesenswert?

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?
#3159177
Lesenswert?

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.
#3159179
Lesenswert?

> 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?
Gast #3159182
Lesenswert?

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.
Gast #3159207
Lesenswert?

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.
Gast #3159211
Lesenswert?

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
Gast #3159218
Lesenswert?

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 :-)
#3159223
Lesenswert?

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 );
Gast #3159239
Lesenswert?

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!
#3159249
Lesenswert?

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.
Gast #3159253
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren