Verwenden von Funktionen ohne vorige definition.

Gast #2607864
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;)
Gast #2607936
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.
Gast #2607939
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.
Gast #2607945
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.
#2608704
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.

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