Dlaczego prototypy funkcji w C chronią Cię przed ukrytymi błędami

0
4

Nie musisz widzieć całej treści funkcji, aby wiedzieć, jak ją wywołać. Wszystko czego potrzebujesz to obietnica. Ta obietnica jest prototypem funkcji.

We współczesnym C wstępna deklaracja prototypów jest obowiązkowa. Mówi kompilatorowi dokładnie, czego oczekuje funkcja: nazwa, typy argumentów i wartość zwracana. Bez tego działasz na ślepo. A w C ślepota ma swoją cenę.

Ukryty koszt braku prototypowania

Rozważ ten fragment kodu. Wygląda na niewinnego. Kompiluje się. Jest wykonywana.

Tutaj „add” wyraźnie wymaga dwóch liczb całkowitych. Ale tylko jeden transmituje połączenie. Ścisły kompilator byłby oburzony. Wiele osób tego nie robi. Domyślnie zakładają, że typem zwracanym jest „int” i całkowicie ignorują niedopasowania parametrów.

Wynik? Błędne odpowiedzi. Ciche uszkodzenie danych. Spędzasz godziny szukając błędu, który patrzył ci w twarz w drugiej linii.

Dzieje się tak, ponieważ domyślne dziedziczone zachowanie C oczekuje, że funkcje bez prototypów zwrócą „int”. Jeśli aktualna funkcja zwróci wartość „float”, kompilator błędnie zinterpretuje bity. Prototyp to naprawia. Egzekwuje umowę.

Egzekucja umowy

Umieść prototyp na początku. Gdzieś przed pierwszym telefonem.

Kompilator zgłasza teraz błąd. Wie, że polecenie „add” wymaga dwóch argumentów. Odmawia skompilowania wywołania z niewłaściwymi argumentami. Oszczędzasz godziny debugowania.

Stary styl kontra nowoczesny C

Kompilatory inne niż ANSI to zupełnie inna historia. Pozwalają na wykorzystanie prototypów, ale z zastrzeżeniem. Lista parametrów musi być pusta.

To informuje kompilator o nazwie i typie zwracanym. Nie mówi nic o argumentach. Nie następuje sprawdzanie błędów. Wróciłeś do punktu wyjścia.

Nowoczesne C (norma ANSI) wymaga jawnych typów w prototypie. To eliminuje niejasności. Wykrywa niezgodności typów. Świadczy to o braku argumentów. On odkrywa wszystko.

Praktyczne kroki

  1. Refaktoryzacja sortowania bąbelkowego. Przenieś logikę do funkcji. Zgłoś prototyp. Przekaż tablicę i rozmiar jawnie.
  2. Izolacja wejścia Utwórz oddzielną funkcję dla danych wejściowych użytkownika. Nie zaśmiecaj „głównego”. Zgłoś prototyp. Przetestuj to.

Tu nie chodzi o punkty za styl. Chodzi o poprawność.

Prototyp to umowa dostarczona przez kompilator. Zniszcz go, a kompilacja się nie powiedzie.

Możesz się zastanawiać, dlaczego jest to ważne, jeśli Twój kod działa. Jest to ważne, ponieważ błędy w czasie wykonywania są trudniejsze do skorygowania niż błędy w czasie kompilacji. Zatrzymuje Cię błąd kompilacji. Błąd wykonania jest ukryty w środowisku produkcyjnym.

Różnica między niezawodnym i delikatnym programem często sprowadza się do tych kilku linijek na początku. Nie przegap ich.

Kompilator jest po to, żeby Ci pomóc. Posłuchaj go.

попередня статтяJak działają serwery: ukryte silniki Internetu
наступна статтяJak działają automatyczne dialery: od telemarketingu po powiadomienia alarmowe