mikrocontroller.net

Forum: Compiler & IDEs wozu Prototypen deklarieren?


Autor: Melder (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servus

warum braucht AVRStudio eigentlich immer diese Prototypen-Definition

uint8_t function( uint8_t data);

am Anfang des Quellcodes? Jedesmal wenn ich eine Funktion schreibe, die
irgendwo innerhalb von main() aufrufe, kommt die Warnung einer
"implizit deklarierten Funktion"...

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVRStudio braucht keine Prototypen. Die braucht der Compiler, und zwar
dann, wenn die Funktion vor ihrer Definition bereits aufgerufen wird.
Der Compiler muss vor dem ersten Aufruf wissen, dass eine Funktion des
Namens existiert, auch wenn sie erst später oder in einer anderen
Source-Datei definiert wird. Außerdem muss der Compiler wissen, welche
Datentypen übergeben werden. Die Namen der Übergabe-Parameter (in
diesem Falle "data") müssen hingegen erst bei der Definition bekannt
sein. Es genügt bei einem Prototypen daher auch, zu schreiben (für das
obige Beispiel):
uint8_t function(uint8_t);

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Es genügt

Rein rechtlich: ja.
Gute Idee ist es aber keine.

Zum Thema Prototypen:
Das Ur-C (K&R C) brauchte die noch nicht. Man konnte, musste
aber nicht. Es trat dann die 'implizit-int' Rgel in Kraft.
D.h. der Return-Typ der Funktion wurde implizit ls int
angenommen. Die Datentypen der Argumente konnte sich der
Compiler ja aus em Funktionsaufruf ableiten.

Das brachte dann so lustige, und für den unbedarften Programmierer
ausserst schwer zu findende, Fehler, wie:
int main()
{
  double x;

  x = sin(0);
}

und jetzt such mal schön :-)
* Da kein Prototyp für sin vorhanden ist, geht der Compiler
davon aus, dass die Funktion einen int returned. Tut sie
aber nicht. sin liefert einen double. D.h. die Funktion
legt einen double für den Rückgabemechanismus bereit, der
Aufrufer hingegen behandelt die Bytes als ob sie ein int wären.
* Da kein Prototyp für sin vorhanden ist, muss der Compiler die
Argumenttypen aus dem Aufruf ableiten. Im obigen Fall kommt er
zum Schluss, dass sin wohl einen int nehmen wird, da ja 0 ein
int darstellt. D.h. der Compiler baut den Aufruf so, dass als
Argument die Bytes für einen int übergeben werden.
Nur: sin nimmt einen double! d.h. die Implementierung für sin
nimmt die Bytes die es kriegen kann und interpretiert sie
als double.
* mal davon abgesehen, dass sizeof(int) meistens nicht gleich
sizeof(double) ist, haben int und double aber auch völlig andere
Repräsentierungen als Bytes, so dass hier ein heilloses Durcheinander
ensteht.

Abhilfe schafft nur ein Prototyp:
double sin(double);

int main()
{
  double x;

  x = sin(0);
}

Jetzt weiss der Compiler, dass es eine Funktion namens 'sin'
gibt (könnte ja auch ein Tippfehler sein), dass die Funktion
einen double erwartet und einen double zurückliefert.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat auch was mit Programmierphilosophie zu tun, d.h. dem individuellem
Geschmack.

(1) Top Down: main() ist oben, daraus aufgerufene Funktionen darunter,
Kleinkram ganz unten. In diesem Fall kommt man kaum darum herum, die am
Anfang vom Source die Prototypes aufzulisten.

(2) Bottom Up: Genau andersrum. main() ist hinten, der Rest davor.
Prototypes kann man sich meist sparen, es sein denn man hat mit
Rekursion zu tun.

(3) Man programmiert irgendwie, und sei es wild durcheinander, will
aber schon der Übersichtlichkeit halb immer erkennen können, in welchem
Sourcefile welche lokalen Funktionen definiert sind. Und listet sie
daher fein säuberlich oben auf.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.