W języku C prototypy funkcji to deklaracje funkcji, które informują kompilator o typie zwracanym, nazwie i typach parametrów funkcji przed jej faktyczną implementacją. Prototypy zwykle znajdują się w plikach nagłówkowych (.h). Ich zastosowanie pozwala:
Przykład prototypu:
// math_utils.h int sum(int a, int b); // Prototyp funkcji
// main.c #include "math_utils.h" int main() { int result = sum(3, 4); // kompilator wie o sygnaturze sum }
Bez prototypu funkcja byłaby traktowana jako zwracająca int i przyjmująca nieokreśloną liczbę argumentów, co może prowadzić do nieoczekiwanych błędów w czasie wykonywania.
Pytanie: Czy można wywołać funkcję w C przed jej zdefiniowaniem, jeśli nie została zadeklarowana jako prototyp?
Odpowiedź: W standardzie C89 zezwolono na wywoływanie funkcji przed ich zdefiniowaniem, jeśli typ zwracany to int, a parametry nie były sprawdzane (implicit int, implicit promotion). W nowoczesnych standardach prowadzi to do ostrzeżeń lub błędów, i nie należy stosować takiego podejścia.
Przykład błędu:
int main() { foo(1, 2); // Brak prototypu foo } int foo(double x, double y) { ... }
Kompilator wywoła funkcję, traktując parametry jako int, chociaż sygnatura zakłada double — rezultatem jest UB lub niewłaściwe wartości.
Historia
W dużym projekcie naukowym w jednym z modułów brakowało prototypów dla funkcji przetwarzających dane. Przy przekazywaniu
floatzamiastintbłędy ujawniły się dopiero po niepoprawnych obliczeniach na etapie eksploatacji, chociaż kompilacja przebiegała bez błędów.
Historia
W modułowej narzędzi do automatyzacji budowy funkcje były definiowane tylko w plikach
.c, bez deklaracji w nagłówkach. W dwóch modułach zdefiniowano funkcje o tych samych nazwach i niezgodnych parametrach — doprowadziło to do trudnej do uchwycenia błędu związania podczas łączenia.
Historia
W projekcie pod systemy wbudowane pojawił się problem: funkcja inicjalizacji była wywoływana przed jej definicją bez prototypu. Z powodu założeń kompilatora dotyczących typów parametrów i zwracania logika została poważnie zakłócona, a system ulegał awariom tylko w niektórych kompilacjach z różną organizacją pamięci.