Verwenden von Funktionen ohne vorige definition.

Gast #2607864
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 #2607919
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.
Gast #2607936
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
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
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
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

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.