In der Programmiersprache C sind Funktionsprototypen (Function Prototypes) Deklarationen von Funktionen, die den Compiler über den Rückgabetyp, den Namen und die Typen der Parameter der Funktion vor deren tatsächlicher Implementierung informieren. Prototypen werden normalerweise in Header-Dateien (.h) platziert. Ihre Verwendung ermöglicht es:
Beispiel für einen Prototyp:
// math_utils.h int sum(int a, int b); // Funktionsprototyp
// main.c #include "math_utils.h" int main() { int result = sum(3, 4); // Der Compiler kennt die Signatur von sum }
Ohne den Prototyp würde die Funktion als zurückgebend int und annehmend eine undefinierte Anzahl von Argumenten interpretiert werden, was zu unerwarteten Laufzeitfehlern führen kann.
Frage: Kann man eine Funktion in C vor ihrer Definition aufrufen, wenn sie nicht als Prototyp deklariert ist?
Antwort: Im Standard C89 war es erlaubt, Funktionen vor ihrer Definition aufzurufen, wenn der Rückgabewert int war und die Parameter nicht überprüft wurden (implizites int, implizite Promotion). In modernen Standards führt dies zu Warnungen oder Fehlern, und es sollte dieser Ansatz nicht verwendet werden.
Beispiel für einen Fehler:
int main() { foo(1, 2); // Kein Prototyp für foo } int foo(double x, double y) { ... }
Der Compiler wird die Funktion aufrufen und die Parameter als int betrachten, obwohl die Signatur double impliziert — Ergebnis: UB oder falsche Werte.
Geschichte
In einem großen Forschungsprojekt fehlten in einem der Module die Prototypen für die Datenverarbeitungsfunktionen. Bei der Übergabe von
floatanstelle voninttraten die Fehler erst nach fehlerhaften Berechnungen in der Betriebsphase auf, obwohl die Kompilierung ohne Fehler verlief.
Geschichte
In einem modularen Automatisierungstool wurden Funktionen nur in
.c-Dateien definiert, ohne Deklarationen in Header-Dateien. In zwei Modulen wurden Funktionen mit demselben Namen und inkompatiblen Parametern definiert — das führte zu einem schwer fassbaren Bindungsfehler beim Linken.
Geschichte
In einem Projekt für eingebettete Systeme trat ein Problem auf: Die Initialisierungsfunktion wurde vor ihrer Definition ohne Prototyp aufgerufen. Aufgrund der Annahme des Compilers über die Parameter- und Rückgabetypen war die Logik stark gestört und das System hatte nur bei bestimmten Builds mit unterschiedlicher Speicherorganisation Probleme.