Sign in Join
Wiki copytemporary

Conditional compilation/fi: what changed

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

Title: Conditional compilation/fi

OldNewLine
1+## Mitä on ehdollinen kääntäminen?
2+
3+Ehdollinen kääntäminen ottaa mukaan tai jättää pois [[Source code/fi|lähdekoodin]] osia, jos ehto on olemassa tai ei ole.
4+
5+Useimmissa 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]].
6+
7+Niitä voidaan käyttää moniin eri tarkoituksiin, kuten:
8+
9+- Alustakohtaisen koodin eristämiseen
10+- Luonnollisen kielenvalintaan
11+- Avoimen- ja suljetun lähdekoodin osien käyttöoikeudet
12+- Eristämään kokeellista (experimental) ohjelmakoodia
13+- [[Compiler|Kääntäjän]] versioihin
14+- Kirjastoversioihin
15+- jne.
16+
17+[[FPC/fi|Free Pascal]] tukee erilaisia ehdollisen kääntämisen tyylejä:
18+
19+- [[Turbo Pascal/fi|Turbo Pascal]] ja varhaiset [[Delphi/fi|Delphi]]-tyyliset ohjeet
20+- [[Mac Pascal]] -tyyliset ohjeet
21+- Uudemmat Free Pascal ja Delphi -tyyliset ohjeet
22+- Käännösaikaiset makrot
23+
24+Huomaa, 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.
25+
26+## Turbo Pascal tyyliset ohjeet
27+
28+Turbo 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.
29+
30+Tämä tarkoittaa myöhemmin, että voidaan laajentaa tiettyjen direktiivien merkitystä, kuten esimerkiksi. `{$DEFINE}` makrojen yhteydessä.
31+
32+### \$define
33+
34+`{$DEFINE}`-ohje yksinkertaisesti ilmoittaa tunnisteen, jota voidaan myöhemmin käyttää ehdolliseen kääntämiseen:
35+
36+``` pascal
37+{$DEFINE name} // Määrittää tunnisteen nimeltä "name"
38+```
39+
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
41+
42+``` pascal
43+{$DEFINE DEBUG}
44+```
45+
46+lähdekoodissa.
47+
48+### \$undef
49+
50+`{$UNDEF}`direktiivissä määritellään aiemmin määritelty symboli. Tässä on esimerkki, jota voidaan käyttää:
51+
52+``` pascal
53+// Some older source code is polluted with {$IFDEF FPC} that are no
54+// longer necessary depending on the Delphi version to which it it should be compatible.
55+// I always test this by trying this on top of the program or unit:
56+{$IFDEF FPC}
57+ {$MODE DELPHI}
58+ {$UNDEF FPC}
59+ {$DEFINE VER150}
60+ // code will now compile as if it was Delphi 7, provided the original Delphi source code was indeed written for Delphi 7 and up.
61+{$ENDIF}
62+```
63+
64+### \$ifdef ja \$endif
65+
66+Yksinkertaisin tapa määrittää ehdollisen koodin lohko on näin:
67+
68+``` pascal
69+unit cross;
70+{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
71+```
72+
73+Yllä oleva esimerkki on varsin yleinen lähdekoodissa, joka on koottava sekä Delphissä että Free Pascalissa
74+
75+Jos 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]].
76+
77+Ehdollinen 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}`.
78+
79+Vastaavia lohkoja voidaan auttaa tunnistamaan käyttämällä esim. sisennystä, mutta voidaan käyttää myös [[Comments/fi|kommentteja]]:
80+
81+``` pascal
82+{$IFDEF FPC this part is Free Pascal specific}
83+// some Free Pascal specific code
84+{$ENDIF Free Pascal specific code}
85+```
86+
87+> **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.
89+
90+``` pascal
91+// Täysin väärin ymmärretty ohjelma
92+{$define blue}
93+begin
94+{$ifdef red or $ifdef blue}// kaikki red:n jälkeen on kommenttia
95+ writeln ('red or blue'); // tätä koodia ei koskaan suoriteta ellei red ole voimassa
96+{$endif red or blue} // kaikki $endif:n jälkeen on kommenttia.
97+end.
98+```
99+
100+### \$ifndef
101+
102+Tämä on päinvastainen kuin `{$IFDEF}` eli koodi sisältyy tiettyyn ehtoon, jota <b>ei</b> ole määritelty. Yksinkertainen esimerkki on:
103+
104+``` pascal
105+{$IFNDEF FPC Tämä osa ei kuulu Free Pascal kääntäjälle}
106+// jotain erityistä koodia mitä Free Pascal ei käännä
107+{$ENDIF koodin osa päättyi joka oli vain muille kääntäjille kuin Free Pascal}
108+```
109+
110+### \$else ja \$elseif
111+
112+`{$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.
113+
114+``` pascal
115+{$IFDEF red}
116+ writeln('Red is defined');
117+{$ELSE no red}
118+ {$IFDEF blue}
119+ writeln('Blue is defined, but red is not defined');
120+ {$ELSE no blue}
121+ writeln('Neither red nor blue is defined');
122+ {$ENDIF blue}
123+{$ENDIF red}
124+```
125+
126+Tä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:
127+
128+``` pascal
129+{$IF Defined(red)}
130+ writeln('Red is defined');
131+{$ELSEIF Defined(blue)}
132+ writeln('Blue is defined');
133+{$ELSEIF Defined(green)}
134+ writeln('Green is defined');
135+{$ELSE}
136+ writeln('Neither red, blue or green. Must be black...or something else...');
137+{$ENDIF}
138+```
139+
140+Tämä on paljon luettavampi.
141+
142+### \$ifopt
143+
144+`{$IFOPT}` -toiminnolla voidaan tarkistaa, onko tietty kääntämisvaihtoehto määritetty.
145+
146+Programmers manual:
147+
148+` 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      `\
149+` the specified state, then compilation continues after the corresponding ``{$ELSE}`` or ``{$ENDIF}`` directive.`
150+
151+Esimerkiksi:
152+
153+``` pascal
154+ {$IFOPT M+}
155+ Writeln(’Compiled with type information’);
156+ {$ENDIF}
157+```
158+
159+Kää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ä.
160+
161+Yleisesti tätä käytetään kun testataan onko DEBUG tila käytössä:
162+
163+``` pascal
164+{$IFOPT D+}{$NOTE debug-tila on käytössä}{$ENDIF}
165+```
166+
167+Tä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:
168+
169+`# ----------------------`\
170+`# Defines (preprocessor)`\
171+`# ----------------------`\
172+`#`\
173+`# nested #IFNDEF, #IFDEF, #ENDIF, #ELSE, #DEFINE, #UNDEF are allowed`\
174+`#`\
175+`# -d is the same as #DEFINE`\
176+`# -u is the same as #UNDEF`\
177+`#`\
178+`#`\
179+`# Some examples (for switches see below, and the -? help pages)`\
180+`#`\
181+`# Try compiling with the -dRELEASE or -dDEBUG on the command line`\
182+`#`\
183+`# For a release compile with optimizes and strip debug info`\
184+`#IFDEF RELEASE`\
185+`  -O2`\
186+`  -Xs`\
187+`  #WRITE Compiling Release Version`\
188+`#ENDIF`
189+
190+## Mitä ei saa tehdä
191+
192+Mitä vikaa tässä koodissa? Voitko havaita sen?
193+
194+``` pascal
195+var
196+ MyFilesize:
197+ {$ifdef Win32}
198+ Cardinal
199+ {$else}
200+ int64
201+ {$endif}
202+```
203+
204+Vastaus on:
205+
206+- 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ä]].
207+- useimmilla 64-bittisillä alustoilla suurin tiedostokoko on [[QWord/fi|QWord]] ei [[Int64/fi|Int64]].
208+
209+Tä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ä!
210+
211+On aina hyvä ymmärtää tällaisia ​​asioita erityisesti ja että tällaiset asiat voidaan helposti korjata.
212+
213+``` pascal
214+var
215+ MyFilesize:
216+ {$if defined(Win32)}
217+ Cardinal
218+ {$elseif defined(Win64)}
219+ Qword;
220+ {$else}
221+ {$error this code is written for win32 or win64}
222+ {$endif}
223+```
224+
225+Tähän on ratkaisu, joka ei käytä ehtoja lainkaan:
226+
227+``` pascal
228+var
229+ MyFilesize:NativeUint;
230+```
231+
232+Mitä vikaa tässä koodissa?
233+
234+``` pascal
235+
236+{$IFDEF BLUE AND $IFDEF RED} Form1.Color := clYellow; {$ENDIF}
237+{$IFNDEF RED AND $IFNDEF BLUE} Form1.Color := clAqua; {$ENDIF}
238+```
239+
240+Vastaus on:
241+
242+- Katso kohtaa missä kerrottiin **kommenteista** ja varoitettiin niistä
243+- Kääntäjän ohjeet siis ohjaavat käännöstä.
244+
245+---
246+*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