Sign in Join
Wiki copytemporary

Exceptions/fi: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Exceptions/fi

OldNewLine
1+# Poikkeukset
2+
3+[[FPC/fi|Free Pascal]] tukee poikkeuksia. Poikkeukset ovat hyödyllisiä virheiden käsittelyssä ja resurssien vuotojen välttämisessä. Muista kuitenkin, että poikkeuksilla on suorituskykyvaikutusta.
4+
5+Virallinen dokumentaatio löytyy täältä: [Reference guide chapter 17](https://www.freepascal.org/docs-html/ref/refch17.html).
6+
7+Oletuksena poikkeukset on pois käytöstä. Se voidaan valita käyttöön kun käytetään [[Mode ObjFPC|ObjFPC]] tai [[Mode Delphi|DELPHI]] [[Compiler Mode/fi|kääntäjän moodia]] tai lisäämällä parametrin -Sx [[Compiler/fi|kääntäjän]] [[Command-line interface/fi|komentoriville]]. Tämä mahdollistaa [[Try/fi|try]], [[Raise/fi|raise]], [[Except/fi|except]] ja [[Finally/fi|finally]] [[Reserved word/fi|varatut sanat]] käytettäväksi omassa koodissasi, mutta se ei salli poikkeuksia [[RTL/fi|RTL]]:stä. Jotta RTL voi nostaa poikkeuksia sen sijaan, että se tuottaa [[runtime error/fi|ajonaikaisia virheitä]], käytä ohjelman SysUtils-käännösyksikköä.
8+
9+Poikkeusten kantaluokka `Exception` löytyy SysUtils [1](https://www.freepascal.org/docs-html/rtl/sysutils/exception.html) käännösyksiköstä. Kaikissa poikkeuksissa tulisi käyttää tätä [[Class/fi|luokkaa]] tai jotain siitä johdettua luokkaa.
10+
11+SysUtils luo automaattisesti peruspoikkeusten kiinnioton, joten mikä tahansa muutoin jäänyt poikkeus näkyy ihmisen luettavissa muodossa, kun ohjelma päättyy. Luodaksesi luettavia callstacks omasta koodistasi pyydetyistä poikkeuksista, ei välttämättä lopeta ohjelmaa, voidaan käyttää SysUtils-functions `ExceptAddr`, `ExceptFrames`, `ExceptFrameCount`, and `BackTraceStrFunc`.
12+
13+## Esimerkit
14+
15+Huomaa, että [[Pascal/fi|Pascal]] käyttää eri [[Keyword|avainsanoja]] kuin jotkut muut kielet: `raise` vastaa `throw`:ta ja `except` vastaa `catch`:a. Myös kääntäjä on suunniteltu niin että valinnan mukaan kukin `try`-lohko voidaan yhdistää joko `except` tai `finally`-lohkoon, mutta ei molempiin samanaikaisesti. Jos tarvitaan sekä `except` että `finally`-lohkoa suojaamaan samaa koodia niin ne laitetaan sisäkkäin.
16+
17+### Virheiden käsittely
18+
19+``` pascal
20+uses sysutils;
21+
22+begin
23+ try
24+ // Tee jotain, joka saattaa mennä pieleen.
25+ except
26+ on E : Exception do begin
27+ // Yritä palauttaa tai näytä käyttäjälle virheilmoitus
28+ end;
29+ end;
30+end.
31+```
32+
33+### Resurssien siivoaminen
34+
35+``` pascal
36+try
37+ // Tee jotain, joka saattaa mennä pieleen.
38+finally
39+ // Siivoa resurssi lopuksi (kutsutaan aina, myös poikkeus tilanteissakin).
40+end;
41+```
42+
43+### Poikkeusten vuoto
44+
45+Finally-lohkot eivät aina tuhoa poikkeusolioita. Kaikki poikkeukset, jotka saavuttavat ohjelman "lopun". käynnistää muistivuodon varoituksen. Tällaisten poikkeusten kuluttamiseen voidaan käyttää ylimääräistä poikkeuslohkoa. Tämä koskee [Delphi-yhteensopivuus](https://bugs.freepascal.org/view.php?id=33650).
46+
47+``` pascal
48+begin
49+ try
50+ // Pääohjelma, jossa luodaan poikkeusolio.
51+ finally
52+ try
53+ // puhdistuskoodi.
54+ except
55+ end;
56+ end;
57+end.
58+```
59+
60+### Poikkeuksen nostaminen
61+
62+``` pascal
63+raise Exception.Create('Jokin hyödyllinen kuvaus siitä, mikä meni pieleen');
64+```
65+
66+### Käytä omia erikoistuneita poikkeustyyppejä eri ongelmien ilmoittamiseen
67+
68+``` pascal
69+type EMyLittleException = Class(Exception);
70+
71+begin
72+ try
73+ raise EMyLittleException.Create('Foo');
74+ except
75+ on E : EMyLittleException do writeln(E.Message);
76+ on E : Exception do writeln('This is not my exception!');
77+ else writeln('This is not an Exception-descendant at all!');
78+ end;
79+end;
80+```
81+
82+### Poikkeusten uudelleen nostaminen
83+
84+``` pascal
85+try
86+ // Tee jotain, joka voi mennä pieleen.
87+except
88+ // Yritä palauttaa tai näyttää käyttäjälle virhesanoma.
89+ if recoveredSuccessfully = FALSE then
90+ raise;
91+end;
92+```
93+
94+## Poikkeusluokat
95+
96+Käännösyksikkö SysUtils määrittelee ja nostaa monia erityisiä [poikkeusluokkia](https://www.freepascal.org/docs-html/rtl/sysutils/index-4.html)
97+
98+Kun käännösyksikkö SysUtils on mukana ohjelmassa ja poikkeukset on otettu käyttöön, erilaisia [runtime-virheitä](https://www.freepascal.org/docs-html/user/userap4.html) muutetaan poikkeuksiksi. Prosessoritason keskeytykset, kuten SIGSEGV tai SIGFPU, jotka yleensä kääntyvät ajonaikaisvirheisiin, muutetaan myös poikkeuksiksi. Esimerkiksi run-time error 200 eli ajonaikainen virhe 200 (nollalla jako) muuttuu EDivByZero:ksi tai EZeroDivide:ksi, kun taas ajonaikainen virhe 216 (yleinen suojausvirhe, general protection fault) tulee EAccessViolation:ksi.
99+
100+## Parhaat käytännöt
101+
102+- Nostetaan poikkeuksia vain silloin kuin toimenpidettä ei voitu saattaa päätökseen, jos se olisi tavallisesti onnistunut.
103+- Ei käytetä poikkeuksia osana odotettua ohjelman suoritusta. Sen sijaan lisätään tarkistuksia tavallisten virheiden ehtoihin ja palautetaan virhearvot perinteiseen tapaan. Esimerkiksi syötteen jäsentämiseen liittyvät ongelmat tai tiedoston olemassaolo yleensä eivät ole todella poikkeuksellisia.
104+- Mutta nostetaan poikkeus, jos on kriittinen virhe havaitaan; ohjelmoijat voivat unohtaa tarkistaa palautetut virhearvot.
105+- Nimeämiskäytäntö: Etuliite poikkeusluokan nimillä, joka on iso E-kirjain.
106+- Uudelleen nostetaan poikkeus `except` -lohkossa käyttämällä `raise` käskyä jos ei kyetä toipumaan ongelmasta; tämä säilyttää alkuperäisen poikkeuksen callstackin.
107+- Pitää olla varovainen, kun käytetään catch-all `Exception` luokkaa, koska alla oleva koodi, käyttöjärjestelmä tai tiedostojärjestelmä saattaa tuottaa odottamattoman poikkeuksen, joka saattaa mennä tällöin poikkeustilanteesta läpi, mikä voi mahdollisesti pilata ohjelman suorituksen.
108+- Kun käännösyksikköä tai kirjastoa kirjoitetaan, jos poikkeuksia käytetään niin ne on dokumentoitava selvästi. Näin käännösyksikön käyttäjä tietää, mitä odottaa.
109+- Pidetään poikkeusten käsittely pois koodista, joka on suoritettava mahdollisimman nopeasti.
110+
111+## Suorituskyky
112+
113+Kääntäjän optimointitasot ei tuo paljon eroja poikkeuksiin. Kaikissa poikkeuslohkoissa on pieni määrä "kehyskoodia", jota ei voida optimoida. Toki on mahdollista, että kääntäjä tuottaa poikkeuskoodin, jolla on erilaisia suorituskykyvaikutuksia. FPC 3.0.4: sta lähtien oletuspoikkeusmekanismi käyttää standardia setjmp / longjmp-tyyliä. FPC tukee myös OS-järjestelmään perustuvaa strukturoitua poikkeuksenkäsittelyä; tämä on Win64: n oletusarvo, ja se voidaan ottaa käyttöön Win32: ssä (käännä kääntäjällä uudelleen`$define TEST_WIN32_SEH`). Muita mekanismeja tullaan todennäköisesti lisäämään FPC:hen tulevaisuudessa.
114+
115+Jotta saadaan parempi tuntuma, mitä tapahtuu, kokeile pienen testiohjelman kirjoittamista ja kääntämistä -a -kytkimellä. Tämä tekee ihmisen luettavissa olevan assemblytiedosto.
116+
117+Metodeita setjmp/longjmp koskevat huomautukset:
118+
119+- `Try`-lauseessa lisätään ylimääräisiä osoitteen laskemista, pinoon laittoa (push) ja siitä poistoa (pop), joitakia suoria hyppykäskyjä ja ehdollisen hypyn.
120+- `Except`-lause lisää yllä olevan pinoon laittoa (push) ja siitä poistoa (pop), enemmän suoria hyppykäskyjä ja toisen ehdollisen hypyn. Tämä on poikkeuskehyksen asetus "kustannus", vaikka poikkeusta ei esiintyisi.
121+- `Finally`-lause lisää pinosta poiston (pop) ja ehdollisen hyppyn, jotta poikkeus voidaan nostaa uudelleen.
122+- `Raise`-lause luovat merkkijonon ja ohittaa FPC:n hallinnan poikkeuksen noston.
123+- `Raise`-lause luovat merkkijonon ja välittävät ohjauksen FPC: n poikkeustarkistukseen. Merkkijonon luominen itsessään voi synnyttää implisiittisen poikkeuskehyksen funktiolle / aliohjelmalle dynaamisten merkkijärjestelyjen vuoksi, vaikka raise ei toteutuisi. Siksi esim. konttityypit näkevät usein raisen erillisenä paikallisena (yksityisenä) aliohjelmana. Tämä lokalisoi poikkeusrungon kyseiseen aliohjelmaan, joten suorituskyvyn osuma toteutetaan vain, jos aliohjelmaa kutsutaan.
124+
125+Lisäksi ihmisen luettavissa olevan callstackin luominen korotetusta poikkeuksesta käsittää aikaa vievän pinonsiirron ja merkkikäsittelyn.
126+
127+Kuten sanottiin, että raskas koodin käsittely kyseisen kohdan ulkopuolella poikkeuksella yleensä ylittää niiden suorituskykyvaikutukset. Ei pidä tuntea pahaa siitä, että pystyy kirjoittamaan parempaa ohjelmakoodia.
128+
129+## Katso myös
130+
131+[[Logging exceptions]]
132+
133+[[Avoiding implicit try finally section]]
134+
135+[Exceptions vs Error codes](http://codenewsfast.com/cnf/article/0/permalink.art-ng53q201750) - a situation where exceptions might be a danger in some code (see middle of this page)
136+
137+---
138+*From the Free Pascal wiki, page "Exceptions/fi", as it stood on 2022-08-06 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history