Forum: Compiler & IDEs Verwenden von Funktionen ohne vorige definition.


von C Anfänger (Gast)


Lesenswert?

Aus dem Buch C von A bis Z Kapitel 9.5 geht heraus, dass Funktionen, die 
nach der Main Methode definiert werden vor der Main Methode deklariert 
werden müssen.

Wer kann mir also erklären wieso mein Programm im AVR Studio 5 Simulator 
Atmega8 funktioniert?
1
#include <avr/io.h>
2
3
int i = 0;
4
5
int main(void)
6
{
7
  
8
    DDRB = 255;
9
  
10
    while(1)
11
    {
12
       i++;
13
       PORTB = i;
14
       if(i == 10)
15
       {
16
         x();
17
       }      
18
         
19
    }
20
    return 1;
21
}
22
23
void x()
24
{
25
  i = 0;
26
}

Wäre dankbar für eine plausiblle erklärung;)

von Facebook (Gast)


Lesenswert?

Also, das wäre wohl ein Verhalten nach ANSI-C..so wie du das gelesen 
hast.

Nun hat sich ATMEL eventuell gedacht, dass sie das in ihrem Compiler 
ganz eifnach anders machen.

von Peter II (Gast)


Lesenswert?

in C ist das meines wissens zulässsig. Das gibt eventuell eine Warnung 
aber mehr nicht. Du kannst auch x mit irgendwelchen anderen Paramtern 
aufrufen

int y = x(1,2,3,4);

dann wird es vermutlich auch compileren, beim starten könnten aber dann 
so ziemlich alles Passieren was man sich vorstellen kann.

von DirkB (Gast)


Lesenswert?

Der Compiler versucht dann aus dem Aufruf auf die Parameterliste zu 
schließen.
ES sollte eine Warnung geben.

Wenn du in main mal
1
x(2.0);
2
...
3
x(1);
4
...
5
6
 
7
void x(int y)
8
{
9
  i = y;
10
}
 wird er x mit double als Paramter annehmen (1. Aufruf)
Beim 2. Aufruf  wird er dann die Integer 1 in double wandeln.

von Dario B. (abcd)


Lesenswert?

vllt. weil du einen gnädigen compiler/präprozessor hast, der vor dem 
kompilieren den prototypen ergänzt?

von Peter D. (peda)


Lesenswert?

C Anfänger schrieb:
> Wäre dankbar für eine plausiblle erklärung;)

Du übergibst nichts und returnst nichts, also ist der Typ wurscht.
Krachen tuts erst, wenn != nichts oder != int übergeben/returnt wird.

Du solltest aber trotzdem die Warnungen lesen und beheben.


Peter

von Peter II (Gast)


Lesenswert?

Dario B. schrieb:
> vllt. weil du einen gnädigen compiler/präprozessor hast, der vor dem
> kompilieren den prototypen ergänzt?

nein das ist C. Bein einem Funktionsaufruf werden einfach der reihe nach 
die werte auf den Stack gelegt und dann einfach ein Call auf die Adresse 
gemacht. Dem compiler ist es ziemlich egal was er für werte auf den 
Stack legt. Wenn du ihm keine prototypen vorgibst, dann verwendet er 
einfach die Datentypen die übergeben werden.

Das man soetwas in der Praxis nicht machen sollte ist klar.

von C Anfänger (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Du solltest aber trotzdem die Warnungen lesen und beheben.

Ja, hatte die Warnung nicht gesehen.
Jetzt passt das zumindest alles wieder zam.
Passt, danke allen!

von Adib (Gast)


Lesenswert?

Ich dachte mal im C ist eine nicht deklarierte Funktion.
Int foo(void)

Adib.

von Rolf M. (rmagnus)


Lesenswert?

Adib schrieb:
> Ich dachte mal im C ist eine nicht deklarierte Funktion.
> Int foo(void)

Im Bezug auf den Return-Typ stimmt das auch. Der ist in dem Fall immer 
int. Aber wenn ich Paramter übergebe, dann geht der Compiler davon aus, 
daß die Funktion genau diese Paramter auch haben will.
Das ist z.B. auch der  Grund, warum empfohlen wird, bei malloc keinen 
Cast zu machen in der Art:
1
meintyp* p = (meintyp*)malloc(sizeof *p);

Dieser Cast ist in C nicht nötig, und wenn man vergessen hat, den Header 
für malloc zu includen, geht der Compiler davon aus, daß malloc einen 
int zurückliefert, was natürlich Unsinn ist. Normalerweise käme da eine 
Warnung, aber der Cast unterdrückt diese.

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.