[nem-pl] Uwagi różne

Marcin 'Qrczak' Kowalczyk qrczak at knm.org.pl
Sat Feb 21 11:51:57 CET 2004


W liście z sob, 21-02-2004, godz. 11:20, "Paweł W. Olszta" pisze:

> No nie, to jest tak, że błąd w tym miejscu powienien wyskoczyć zawsze, 
> jeśli kompilator nie potrafi sobie zinferować, że x jest różne od zera 
> (np. bo zobaczy wcześniej odpowiedniego if'a albo assert (x != 0)).

Błąd kompilacji? Żaden język tego nie robi przy dzieleniu przez nieznaną
liczbę! I słusznie: bo zwykle to, że wartość jest zawsze różna od zera,
nie wynika z kodu w tak oczywisty sposób, żeby kompilator to zauważył
(tym bardziej że reguły poprawności programu powinny być ścisłe, więc
zauważenie musi być w jakiś ładnie specyfikowalny sposób, a nie "kiedy
akurat kompilatorowi się uda").

Na przykład dana funkcja po prostu nigdy nie jest wołana z argumentami,
z których wychodzi 0, tylko system typów nie jest w stanie tego opisać.

A jeśli łatwo nie wynika, to jedyne, co programista może zrobić, to
wstawić jawne sprawdzenie, które w przypadku zera rzuci wyjątkiem. Czyli
zrobi dokładnie to samo, co dzielenie nie sygnalizujące błędu w czasie
kompilacji. Więcej takich sytuacji i wkurzony programista po prostu
zdefiniuje sobie funkcję, która robi
   if (y == 0) throw DivideByZero
   else x / y
czyli nie zyskał nic, tylko stracił na czytelności.

Dzielenie przez zero to tylko przykład.

Twoja filozofia jest sprzeczna z filozofią Erlanga, której hasło to "let
it crash" i mówi mniej więcej tak: sprawdzaj jawnie poprawność danych
tylko na wejściu; w środku programu zakładaj, że dane są poprawne; ale
pisz program tak, żeby w przypadku bezsensownych danych dany proces
wyłożył się jak najszybciej - nie próbował się domyślać, jakie te dane
miały być, nie próbował zwracać odpowiedzi mówiącej "złe dane", tylko po
prostu się wyłożył; taki proces zostanie zrestartowany przez proces
nadzorujący dany proces.

("Proces" w terminologii Erlanga odpowiada bardziej wątkowi, przy czym
procesy nie mają wspólnej pamięci, tylko wymieniają się komunikatami,
więc nie ma niebezpieczeństwa pozostawienia współdzielonych danych w
stanie sieczki. Wyłożenie się jest czymś w rodzaju rzucenia wyjątku.)

Dzięki temu program jest bardziej czytelny, bo nie ma jawnego
sprawdzenia wszystkich błędnych sytuacji na każdym kroku, i bardziej
niezawodny, bo program nie próbuje maskować błędów.

Od błędów są wyjątki, a nie jawne sprawdzanie.

> A to dlatego, że interesuje nas język/kompilator, w którym się pisze 
> programy bezpieczne. Z doświadczenia wiem, że zakładanie, że programista 
> wie co robi kończy się katastrofą ;)

Bezpieczne to znaczy
1. procesor nie idzie w krzaki, błędy są zauważane przez rantajm
   (antyprzykład: C i C++),
2. błędy wykonania są sygnalizowane, a nie maskowane (antyprzykład:
   Perl).

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak at knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/





More information about the devel-pl mailing list