Sign in Join
Wiki copytemporary

Conditional compilation/fi: what changed

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

OldNewLine
11## Mitä on ehdollinen kääntäminen?
22
33Ehdollinen kääntäminen ottaa mukaan tai jättää pois [[Source code/fi|lähdekoodin]] osia, jos ehto on olemassa tai ei ole.
44
55Useimmissa käännetyissä kielissä tämän mahdollistavia ominaisuuksia kutsutaan käännösaikaiseksi direktiiveiksi. Käännösaikaiset direktiivit mahdollistavat koodin lohkon kääntämisen, joka perustuu ehtojen läsnäoloon tai puuttumiseen [[Compile time/fi|käännösaikana]]. Ne kuuluvat [[Compiler directive/fi|kääntäjän ohjeisiin]].
66
77Niitä voidaan käyttää moniin eri tarkoituksiin, kuten:
88
99- Alustakohtaisen koodin eristämiseen
1010- Luonnollisen kielenvalintaan
1111- Avoimen- ja suljetun lähdekoodin osien käyttöoikeudet
1212- Eristämään kokeellista (experimental) ohjelmakoodia
1313- [[Compiler|Kääntäjän]] versioihin
1414- Kirjastoversioihin
1515- jne.
1616
1717[[FPC/fi|Free Pascal]] tukee erilaisia ehdollisen kääntämisen tyylejä:
1818
1919- [[Turbo Pascal/fi|Turbo Pascal]] ja varhaiset [[Delphi/fi|Delphi]]-tyyliset ohjeet
2020- [[Mac Pascal]] -tyyliset ohjeet
2121- Uudemmat Free Pascal ja Delphi -tyyliset ohjeet
2222- Käännösaikaiset makrot
2323
2424Huomaa, että tässä syntaksissa ei [[case-sensitive|erotella isoja ja pieniä kirjaimia]] koska se vastaa [[Pascal]] syntaksia. Eli käytetään sekä pieniä että isoja kirjaimia.
2525
2626## Turbo Pascal tyyliset ohjeet
2727
2828Turbo Pascal -tyyppisiä ohjeita ovat `{$DEFINE}`, `{$IFDEF}`, `{$ENDIF}`, `{$IFNDEF}`, `{$IFOPT}`, `{$ELSE}`, `{$ELSEIF}` ja `{$UNDEF}`. Tässä kuvaillaan ohjeita tyylin yhteydessä. Jotkut ohjeet määrittelevät toisella tyylillä laajennetun merkityksen.
2929
3030Tämä tarkoittaa myöhemmin, että voidaan laajentaa tiettyjen direktiivien merkitystä, kuten esimerkiksi. `{$DEFINE}` makrojen yhteydessä.
3131
3232### \$define
3333
3434`{$DEFINE}`-ohje yksinkertaisesti ilmoittaa tunnisteen, jota voidaan myöhemmin käyttää ehdolliseen kääntämiseen:
3535
3636``` pascal
3737{$DEFINE name} // Määrittää tunnisteen nimeltä "name"
3838```
3939
40-Huomaa, että voit myös määrittää tunnisteen [[Command-line interface|komentoriviltä]] tai [[IDE/fi|IDEstä]] esimerkiksi <b>-dDEBUG</b> komentorivillä on sama kuin
40+Huomaa, että voit myös määrittää tunnisteen [[Command-line interface|komentoriviltä]] tai [[IDE/fi|IDEstä]] esimerkiksi -dDEBUG komentorivillä on sama kuin
4141
4242``` pascal
4343{$DEFINE DEBUG}
4444```
4545
4646lähdekoodissa.
4747
4848### \$undef
4949
5050`{$UNDEF}`direktiivissä määritellään aiemmin määritelty symboli. Tässä on esimerkki, jota voidaan käyttää:
5151
5252``` pascal
5353// Some older source code is polluted with {$IFDEF FPC} that are no
5454// longer necessary depending on the Delphi version to which it it should be compatible.
5555// I always test this by trying this on top of the program or unit:
5656{$IFDEF FPC}
5757 {$MODE DELPHI}
5858 {$UNDEF FPC}
5959 {$DEFINE VER150}
6060 // code will now compile as if it was Delphi 7, provided the original Delphi source code was indeed written for Delphi 7 and up.
6161{$ENDIF}
6262```
6363
6464### \$ifdef ja \$endif
6565
6666Yksinkertaisin tapa määrittää ehdollisen koodin lohko on näin:
6767
6868``` pascal
6969unit cross;
7070{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
7171```
7272
7373Yllä oleva esimerkki on varsin yleinen lähdekoodissa, joka on koottava sekä Delphissä että Free Pascalissa
7474
7575Jos kääntäjä on Delphi, niin mitään ei tehdä, mutta jos kääntäjä on Free Pascal, se siirtää Free Pascalin kääntämään ja käyttämään [[Mode Delphi/fi|Delphi-tilaa]].
7676
7777Ehdollinen tunniste "FPC" on määritelty järjestelmässä - on olemassa pitkä luettelo niistä. `{$IFDEF}` ja `{$ENDIF}` lohkon syntaksi on symmetrinen: jokaisella `{$IFDEF}`:llä on oma `{$ENDIF}`.
7878
7979Vastaavia lohkoja voidaan auttaa tunnistamaan käyttämällä esim. sisennystä, mutta voidaan käyttää myös [[Comments/fi|kommentteja]]:
8080
8181``` pascal
8282{$IFDEF FPC this part is Free Pascal specific}
8383// some Free Pascal specific code
8484{$ENDIF Free Pascal specific code}
8585```
8686
8787> **Warning:** Kommenttiominaisuutta ei usein ymmärretä. Sillä vain yksi ehto hyväksytään `{$IFDEF}` ehtoon. Kääntäjä olettaa lopun olevan kommenttia.\
88-> Alla oleva koodi suorittaa [[Writeln/fi|writeln]] [[statement/fi|lauseen]], <b> jos ja vain jos red on määritelty </b>. Tässä esimerkissä `{$ifdef blue}` on vain kommenttia! Vaikka määrittely `{$define blue}` on voimassa.
88+> Alla oleva koodi suorittaa [[Writeln/fi|writeln]] [[statement/fi|lauseen]], jos ja vain jos red on määritelty . Tässä esimerkissä `{$ifdef blue}` on vain kommenttia! Vaikka määrittely `{$define blue}` on voimassa.
8989
9090``` pascal
9191// Täysin väärin ymmärretty ohjelma
9292{$define blue}
9393begin
9494{$ifdef red or $ifdef blue}// kaikki red:n jälkeen on kommenttia
9595 writeln ('red or blue'); // tätä koodia ei koskaan suoriteta ellei red ole voimassa
9696{$endif red or blue} // kaikki $endif:n jälkeen on kommenttia.
9797end.
9898```
9999
100100### \$ifndef
101101
102-Tämä on päinvastainen kuin `{$IFDEF}` eli koodi sisältyy tiettyyn ehtoon, jota <b>ei</b> ole määritelty. Yksinkertainen esimerkki on:
102+Tämä on päinvastainen kuin `{$IFDEF}` eli koodi sisältyy tiettyyn ehtoon, jota ei ole määritelty. Yksinkertainen esimerkki on:
103103
104104``` pascal
105105{$IFNDEF FPC Tämä osa ei kuulu Free Pascal kääntäjälle}
106106// jotain erityistä koodia mitä Free Pascal ei käännä
107107{$ENDIF koodin osa päättyi joka oli vain muille kääntäjille kuin Free Pascal}
108108```
109109
110110### \$else ja \$elseif
111111
112112`{$ELSE}` käytetään kääntämään koodia, joka ei kuulu koodilohkoon, jonka määrittelee vastaava `{$IFDEF}`. Se on toimii myös `{$IFOPT}`, `{$IF}` tai `{$IFC}` kanssa.
113113
114114``` pascal
115115{$IFDEF red}
116116 writeln('Red is defined');
117117{$ELSE no red}
118118 {$IFDEF blue}
119119 writeln('Blue is defined, but red is not defined');
120120 {$ELSE no blue}
121121 writeln('Neither red nor blue is defined');
122122 {$ENDIF blue}
123123{$ENDIF red}
124124```
125125
126126Tällainen sisäkkäinen ehdolliseen kääntämiseen kirjoitettu koodi käyttäen edellä mainittua syntaksia voi olla hyvin sotkuista ja lukematonta. Onneksi sitä voidaan yksinkertaistaa käyttämällä `{$ELSEIF}`. Alla on vastaava koodi:
127127
128128``` pascal
129129{$IF Defined(red)}
130130 writeln('Red is defined');
131131{$ELSEIF Defined(blue)}
132132 writeln('Blue is defined');
133133{$ELSEIF Defined(green)}
134134 writeln('Green is defined');
135135{$ELSE}
136136 writeln('Neither red, blue or green. Must be black...or something else...');
137137{$ENDIF}
138138```
139139
140140Tämä on paljon luettavampi.
141141
142142### \$ifopt
143143
144144`{$IFOPT}` -toiminnolla voidaan tarkistaa, onko tietty kääntämisvaihtoehto määritetty.
145145
146146Programmers manual:
147147
148148` The ``{$IFOPT switch}`` will compile the text that follows it if the switch switch is currently in the specified state. If it isn’t in      `\
149149` the specified state, then compilation continues after the corresponding ``{$ELSE}`` or ``{$ENDIF}`` directive.`
150150
151151Esimerkiksi:
152152
153153``` pascal
154154 {$IFOPT M+}
155155 Writeln(’Compiled with type information’);
156156 {$ENDIF}
157157```
158158
159159Kääntää Writeln-lauseen vain, jos tyyppitietojen generointi on käytössä. Huomautus: `{$IFOPT}`-ohje hyväksyyn vain lyhyitä vaihtoehtoja, eli `{$IFOPT TYPEINFO}` ei hyväksytä.
160160
161161Yleisesti tätä käytetään kun testataan onko DEBUG tila käytössä:
162162
163163``` pascal
164164{$IFOPT D+}{$NOTE debug-tila on käytössä}{$ENDIF}
165165```
166166
167167Tällaiset määritykset voivat myös sijaita fpc.cfg: n kaltaisissa määritystiedostoissa, jotka sisältävät myös täydellisen selityksen siitä, miten sitä käytetään:
168168
169169`# ----------------------`\
170170`# Defines (preprocessor)`\
171171`# ----------------------`\
172172`#`\
173173`# nested #IFNDEF, #IFDEF, #ENDIF, #ELSE, #DEFINE, #UNDEF are allowed`\
174174`#`\
175175`# -d is the same as #DEFINE`\
176176`# -u is the same as #UNDEF`\
177177`#`\
178178`#`\
179179`# Some examples (for switches see below, and the -? help pages)`\
180180`#`\
181181`# Try compiling with the -dRELEASE or -dDEBUG on the command line`\
182182`#`\
183183`# For a release compile with optimizes and strip debug info`\
184184`#IFDEF RELEASE`\
185185`  -O2`\
186186`  -Xs`\
187187`  #WRITE Compiling Release Version`\
188188`#ENDIF`
189189
190190## Mitä ei saa tehdä
191191
192192Mitä vikaa tässä koodissa? Voitko havaita sen?
193193
194194``` pascal
195195var
196196 MyFilesize:
197197 {$ifdef Win32}
198198 Cardinal
199199 {$else}
200200 int64
201201 {$endif}
202202```
203203
204204Vastaus on:
205205
206206- että Free Pascal kääntää enemmän CPU-tyyppejä kuin [[32 bit/fi|32-]] ja [[64 bit/fi|64-bittisiä]], myös [[8 bit/fi|8-]] ja [[16 bit/fi|16-bittisiä]].
207207- useimmilla 64-bittisillä alustoilla suurin tiedostokoko on [[QWord/fi|QWord]] ei [[Int64/fi|Int64]].
208208
209209Tässä ohjelmoija joutui ansaan, joka on yleinen: jos käyttää määritelmää niin pitää varmistaa että sen logiikka on vankka. Muuten tällainen koodi voi helposti aiheuttaa ognelmia. Kääntäjä ei havaitse logiikkavirheitä!
210210
211211On aina hyvä ymmärtää tällaisia ​​asioita erityisesti ja että tällaiset asiat voidaan helposti korjata.
212212
213213``` pascal
214214var
215215 MyFilesize:
216216 {$if defined(Win32)}
217217 Cardinal
218218 {$elseif defined(Win64)}
219219 Qword;
220220 {$else}
221221 {$error this code is written for win32 or win64}
222222 {$endif}
223223```
224224
225225Tähän on ratkaisu, joka ei käytä ehtoja lainkaan:
226226
227227``` pascal
228228var
229229 MyFilesize:NativeUint;
230230```
231231
232232Mitä vikaa tässä koodissa?
233233
234234``` pascal
235235
236236{$IFDEF BLUE AND $IFDEF RED} Form1.Color := clYellow; {$ENDIF}
237237{$IFNDEF RED AND $IFNDEF BLUE} Form1.Color := clAqua; {$ENDIF}
238238```
239239
240240Vastaus on:
241241
242242- Katso kohtaa missä kerrottiin **kommenteista** ja varoitettiin niistä
243243- Kääntäjän ohjeet siis ohjaavat käännöstä.
244244
245245---
246246*From the Free Pascal wiki, page "Conditional compilation/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