C: wann braucht man Funktions-Deklarationen?

Moin,

die Theorie sagt, man muss (soll) Funktionen deklarieren.

Funktion();

Aber nur in manchen Fällen beklagt sich der Compiler, wenn man es nicht getan hat. Meistens läuft das Programm auch ohne derartige Deklarationen. Wovon hängt ab, ob man die Deklaration tatsächlich braucht?

Abgesehen davon, dass man sie immer schreiben sollte , oder?

thx
moe.

Mahlzeit Moe!

die Theorie sagt, man muss (soll) Funktionen deklarieren.

Alles andere wird mit Assemblerprogrammierung bestraft.

Funktion();

Das ist keine Deklaration, das geht zwar durch den Compiler aber
dadurch wird es nicht besser.

{
char t[8];

3[t] = 0;
}
Das geht auch durch nen Compiler und ist trotzdem Müll.

Aber nur in manchen Fällen beklagt sich der Compiler, wenn man
es nicht getan hat. Meistens läuft das Programm auch ohne
derartige Deklarationen. Wovon hängt ab, ob man die
Deklaration tatsächlich braucht?

In C sollte es immer eine Warning geben, leider generiert der
Compiler automatisch eine Deklaration wenn die Funktion
über dem Aufruf implementiert ist (wer sich das ausgedacht hat?).

Abgesehen davon, dass man sie immer schreiben sollte ,
oder?

Ja!

Gruß
Stefan

Mahlzeit Moe!

die Theorie sagt, man muss (soll) Funktionen deklarieren.

Alles andere wird mit Assemblerprogrammierung bestraft.

Funktion();

Das ist keine Deklaration, das geht zwar durch den Compiler
aber
dadurch wird es nicht besser.

void Funktion();
aber jetzt, oder? :wink:

{
char t[8];

3[t] = 0;
}
Das geht auch durch nen Compiler und ist trotzdem Müll.

als was?

Aber nur in manchen Fällen beklagt sich der Compiler, wenn man
es nicht getan hat. Meistens läuft das Programm auch ohne
derartige Deklarationen. Wovon hängt ab, ob man die
Deklaration tatsächlich braucht?

In C sollte es immer eine Warning geben, leider generiert der
Compiler automatisch eine Deklaration wenn die Funktion
über dem Aufruf implementiert ist (wer sich das ausgedacht
hat?).

Abgesehen davon, dass man sie immer schreiben sollte ,
oder?

Ja!

Danke
moe.

Mahlzeit Moe!

Funktion();

Das ist keine Deklaration, das geht zwar durch den Compiler
aber dadurch wird es nicht besser.

void Funktion();
aber jetzt, oder? :wink:

Nee!
void Funktion( void );

{
char t[8];

3[t] = 0;
}
Das geht auch durch nen Compiler und ist trotzdem Müll.

als was?

for(:stuck_out_tongue_winking_eye:("\n"),R–:stuck_out_tongue_winking_eye:("|"))for(e=C;e–:stuck_out_tongue_winking_eye:("_"+(*u++/8)%2))P("|"+(*u/4)%2);

Es sollte nur zeigen, nicht alles was einen Compiler fehlerfrei
überwindet sollte man C nennen.
Siehe auch http://www.c-plusplus.de/geschichte.htm

Gruß
Stefan

Hallo moe,

die Theorie sagt, man muss (soll) Funktionen deklarieren.

Funktion();

Wie schon geschrieben ist dies noch der ganz alte K&R Stil aus den Anfängen von C. Wenn der Compiler richtig parametrisiert ist (s.u.) motzt er an dieser Stelle. Richtig wäre:
void Funktion(void);
oder wie halt die Parameter gerade lauten.

Aber nur in manchen Fällen beklagt sich der Compiler, wenn man
es nicht getan hat. Meistens läuft das Programm auch ohne
derartige Deklarationen.

Grundsätzlich sollte man beim Compiler immer diejenige Stufe einstellen, welche die meisten Warnungen erzeugt. Mit dieser Einstellung sollte sich dann das Programm ohne Warnungen übersetzen lassen.
Muss man trotzdem einmal etwas „tricksen“, was den Compiler zu einer Warnung veranlasst, so klammert man dann diese Stelle mit
#pragma warning…
Somit ist dies Stelle dann auch gleich als gewollt dokumentiert.
Allerdings hat man solche Konstrukte nur ganz selten und meist auch nur auf Systemebene.

Wovon hängt ab, ob man die
Deklaration tatsächlich braucht?

Immer wenn der Aufruf einer Funktion vor deren Implementierung erfolgt muss ein Function-Prototype vorhanden sein.
Wenn man ein Modul also Bottom-Up schreibt, kommt man meist ohne Function-Prototype durch. Bei Top-Down sind sie praktisch unumgänglich.

Soweit die Theorie.

Praktisch sollte man alle Prototypes, welche für einen Aufruf von ausserhalb des Moduls gedacht sind, in einer zum Modul gehörenden Header-Datei ablegen und diese auch mit im Modul aufnehmen.
In die Header-datei kommt dann auch die für die Verwendung nötige Beschreibung. Dadurch ist es dann auch möglich ohne grösseren Aufwand Bibliothen zu bilden und zu unterhalten, bzw. jedes Modul hat damit eine definierte und zumindest minimal Dokumentierte Schnittstelle.

Das schlimmste was man machen kann ist die Prototypes „spontan“ direkt beim Aufruf irgendwo im Listing einzubauen.
Wehe man muss ein solches Programm später einmal warten, zumal solche Programmierer auch noch schlecht, bzw. gar nicht, dokumentieren …

MfG Peter(TOO)

hallo Moe,

Ursprünglich war ein ein Funktionsaufruf in C (z.B. y = sin(x):wink:einfach nur eine Anweisung an den Compiler,

  • die übergeben Parameter (hier „x“)auf den Stack zu legen,
  • Zu den Funktion (in diesem Falle „sin“) zu springen
  • nach der Rückkehr mit dem Ergebnis irgendetwas anzufangen (hier nach y schreiben)

die Funktion muss dem Compiler dazu nicht bekannt sein, da er ja weiss, wieviel Bytes jeder Parameter groß ist.

später sucht der Linker, ob er eine Adresse für „sin“ findet, und alles ist prima.

Von daher kann man sich JEDE deklaration in C eigentlich schenken. Erst spätere C-Compiler spucken Warnungen oder Fehler aus. Warum?

!weil nicht alle Menschen perfekt sind!

Wenn eine Funktion (z.B. sin) einen Wert vom Typ double erwartet und zurückgibt, ich aber z.B. ein int gebe, so macht die Funktion mit diesem Wert Unsinn. Der Compiler kann dies nur erkennen, wenn er deren Deklaration kennt.

Und weil die Erfahrung zeigt, dass die Menschen nicht nur nicht perfekt sind, sonder auch, dass sie sich trotzdem dafür halten, stellen sich Compiler halt oftmals zickig an. Und gute Programmierer kasteien sich sogar damit, dass sie „Lint“, benutzen, ein Tool so alt wie die ersten C-Compiler, damit jeder obscurer Code auch sofort gepetzt wird.

Gruß
achim

Abend

die Funktion muss dem Compiler dazu nicht bekannt sein, da er
ja weiss, wieviel Bytes jeder Parameter groß ist.

später sucht der Linker, ob er eine Adresse für „sin“ findet,
und alles ist prima.

Das gilt solange man ausschließlich CDECL (C calling convention)
benutzt ansonsten kracht das Ganze nur.

Da wir aber sicher nicht davon ausgehen können/wollen das die ganze
Welt nur C benutzt ist das kritisch.

Gruß
Stefan

Hallo ihr Beiden,

Und gute
Programmierer kasteien sich sogar damit, dass sie „Lint“,
benutzen, ein Tool so alt wie die ersten C-Compiler, damit
jeder obscurer Code auch sofort gepetzt wird.

Eigentlich befindet sich „Lint“ jetzt im Compiler, wenn man alle Warnungen einschaltet, und wird nicht mehr als eigenständiges Programm benötigt.

MfG Peter(TOO)

Danke!
.