F4. a turbo pascal FORDíTÓ direktívái A Turbo Pascal fordítási lehetőségeinek egy része direktívák felhasználásával vezérelhető. A fordító direktíva, mint speciális megjegyzés jelenik meg a Pascal programban, és minden olyan helyre elhelyezhető, ahol utasítás állhat. A fordító direktívában a megjegyzés nyitó jelét közvetlenül a $ jel követi, amelyet szintén szóköz nélkül követ a direktíva neve. A direktívák az alábbi három szempont alapján csoportosíthatók: Kapcsoló direktívák. Ezek a direktívák a fordító bizonyos lehetőségeit kapcsolják be, ill. ki a direktíva nevét közvetlenül követő + ill. - jelek megadásával. Paraméter direktívák. Ezen direktívák felhasználásával a fordító számára tudunk bizonyos paramétereket definiálni, mint pl. file-név, memóriaméret. Feltételes direktívák. A feltételes direktívák az ún. feltételes fordítást vezérlik, vagyis a felhasználó által definiált feltételes szimbólumoktól függően dől el, hogy egyes programrészek lefordítódnak, vagy nem kerülnek fordításra. A kapcsoló direktívák kivételével a direktíva nevét és a paramétert legalább egy szóköznek kell elválasztania. Nézzünk példákat a direktívák használatára: {$B+} {$R- a tartományellenőrzés kikapcsolása} {$I TIPUSOK.PAS} {$O Editor} {$M 32000,10000,655360} {$DEFINE Debug} {$IFEF Debug} {$ENDIF} A fordítási direktívákat elhelyezhetjük a forrásprogramban - ez a javasolt megoldás, hisz ezen direktívák nagy része programfüggő. De megadhatjuk a direktívákat a Turbo Pascal integrált fejlesztői környezetén (TURBO.EXE) belül az Options-Compiler menüben interaktív módon, ill. a parancssor fordító (TPC.EXE) számára /direktíva alakban vagy a TPC.CFG konfigurációs file-ban. F4.1 A kapcsoló direktívák A kapcsoló direktívák lehetnek globálisak és lokálisak egyaránt. A globális direktíva érvényes a fordítás teljes menetében, míg a lokális direktíva csak a megjelölt programrészlet fordításakor fejti ki hatását. A globális direktívákat a program vagy unit deklarációs része előtt kell elhelyezni, míg a lokális direktívák a programban vagy unit-ban bárhol lehetnek. Megjegyzésben vesszővel elválaszva több kapcsoló is használható: {$B+,R-,S-} $A - Adatok tárolása (5.0) Alapértelmezés: {$A+} Típus : globális A Turbo Pascal változóinak és típusos konstansainak memóriába való elhelyezését szabályozza az $A kapcsoló. A 80x86 CPU-k adatelérése gyorsabb, ha az adatot szóhatárra igazítva tároljuk. Kivétel ez alól a 8088{EMBED Equation |}ć, ahol a fordító nem veszi figyelembe ezt a kapcsolót {$A+} állapot: Ebben az állapotban minden 1 byte-nál hoszabb változó és típusos konstans szóhatárra (páros memóriacímre) igazítva kerül tárolásra. (Ha szükséges, a változók közé nem használt byte-okat helyez a fordító.) A {$A+} nincs hatással a rekordmezőknek és a tömbelemeknek a tárolására. {$A-} állapot: A {$A-} állapotban a változók és a típusos konstansok egyszerűen a következő szabad memóriacímtől kezdve tárolódnak. $B - Logikai kifejezések kiértékelése (5.0) Alapértelmezés: {$B-} Típus : lokális A kapcsoló felhasználásával megválaszthatjuk, hogy az AND és OR operátorokat tartalmazó kifejezésekből milyen módon generálódjék a futtatható programkód. {$B+} állapot: Bekapcsolt állapotban {$B+}, a logikai kifejezéseket teljes egészében kiértékeli a program. {$B-} állapot: A {$B-} állapotban a fordító csak a kifejezés azon részéből generál kódot, amelyik feltétlenül szükséges a kifejezés logikai értékének a meghatáro-zásához. Ez azt jelenti, hogy a kiértékelés a teljes kiértékelés előtt befe-jeződik, ha az eredmény már ismert. $D - Nyomkövetési információk (5.0) Alapértelmezés: {$D+} Típus : globális A nyomkövetéshez szükséges (debug) információk generálását tudjuk a $D kapcsolóval vezérelni. Bekapcsolt {$D+} állapotban a fordítás során egy információs tábla épül fel, amely tartalmazza a hibakereséshez, nyomkövetéshez ill. a hibaforrás file-beli helyének meghatározásához szükséges adatokat. $E - 80x87 emuláció (5.0) Alapértelmezés: {$E+} Típus : globális Az $E kapcsolóval előírhatjuk a fordító számára a 8087 emulátor run- time könyvtár beépítését a programunkba. Ez a könyvtár, ha nincs a gépünkben 80x87 aritmetikai segédprocesszor, képes emulálni azt. A $E kapcsolót általában a $N kapcsolóval együtt használjuk. {$N+,E+} állapot: Ebben az állapotban a Turbo Pascal a teljes emulátor könyvtárat beszerkeszti a programunkba. Az így keletkező .EXE file indításkor ellenőrzi, hogy van-e 80x87 segédprocesszor a gépben, ha van azt használja, de ha nincs akkor az emulátor rutinokat használja. {$N+,E-} állapot: Ebben az állapotban lényegesen kisebb lebegőpontos könyvtár szerkesztődik a programunkhoz. A program azonban csak 80x87 segédprocesszort tartalmazó gépeken futtatható. Az $E kapcsoló nincs hatással a unit-ok fordítására, csak a program- fordításakor veszi figyelembe a fordító. {$N-,E+} állapot: Ha unit-okat és a programot is az {$N-} kapcsolóállás mellett fordítottuk le, akkor az emulátor könyvtár nem szükséges a program futtatásához, így az emulátor kapcsolót figyelmen kívül hagyja a fordító. $F - FAR módú rutinhívások (5.0) Alapértelmezés: {$F-} Típus : lokális {$F+} állapot: Az {$F+} kapcsolót követő eljárások és függvények mindig far (távoli - szegmensek közötti) módon kerülnek meghívásra. {$F-} állapot: Az {$F-} állapotban a Turbo Pascal automatikusan kiválasztja a megfelelő hívási módot: FAR (távoli), ha az eljárást vagy függvényt unit interface részében deklaráltuk. NEAR (közeli), ha az eljárás vagy függvény nem egy unit interface részében került deklarálásra. Overlay modulokat tartalmazó programok esetén ajánlott minden unit és a program elejére helyezni a {$F+} kapcsolót. Eljárás típusú változókat használó programoknál a változóhoz tartozó eljárásokat szintén a {$F+} kapcsolóval kell lefordítanunk. $G - Kódgenerálás a 80286 CPU számára (6.0) Alapértelmezés: {$G-} Típus : lokális {$G-} állapot: Ebben az állapotban generált 8086-os utasítások bármely 80x86 mikro- processzoron futtathatók. {$G+} állapot: A {$G+} állapotban a fordító olyan processzor utasításokat is generál, amelyeket csak 80286 és a későbbi mikroprocesszorok ismernek. Ezekkel az utasításokkal általában gyorsabb kód állítható elő. $I - Az input/output műveletek ellenőrzése (5.0) Alapértelmezés: {$I+} Típus : lokális A $I kapcsolóval vezérelhetjük az I/O eljárások meghívását követő ellenőrző kódrészlet beépítését a programunkba. Ha a program futása során I/O hiba lép fel, ennek lekezelését rábízhatjuk a fordító által generált kódra a {$I+} kapcsolóval, vagy a hibakezelést saját magunk is elvégezhetjük. Ha a {$I-} direktívát használjuk (az ellenőrzés kikapcsolása), akkor az IOResult függvény meghívásával kaphatunk információt a I/O műveletek sikeres-ségéről. $L - Lokális szimbólumok információi (5.0) Alapértelmezés: {$L+} Típus : globális Bekapcsolt állapotban {$L+} engedélyezzük a lokális szimbólumokra vonatkozó nyomkövetési információk generálását, ill. felhasználását a nyomkövetés és hibakeresés során. A unit-okban a lokális szimbólumok információit a .TPU file tartalmazza, megnövelve ezzel a file méretét. A {$L+} kapcsoló használata esetén a program fordításához szükséges memória mérete is megnő. A $L kapcsolót csak akkor veszi figyelembe a fordító, ha a {$D+} direktívát is megadtuk. $N - Lebegőpontos kódgenerálás (5.0) Alapértelmezés: {$N-} Típus : globális A $N kapcsoló segítségével a Turbo Pascal különböző lebegőpontos számítási modelljei közül választhatunk. {$N-} állapot: Az {$N-} állapotban a Turbo Pascal olyan kódot generál, amelyben a valós típusú számításokat run-time könyvtári rutinok végzik el. Ebben a módban csak a Real lebegőpontos típus használható. {$N+} állapot: Bekapcsolt {$N+} állapotban minden valós típusú számításhoz a 8087 aritmetikai társprocesszor számára generál kódokat a fordító. Ha nincs a gépünkben 80x87 processzor akkor emuláltatnunk kell annak működését a {$E+} kapcsoló megadásával. $O Overlay kódgenerálás (5.0) Alapértelmezés: {$O-} Típus : globális Overlay-struktúra kialakítását engedélyezhetjük {$O+}, vagy tilthatjuk {$O-}. Az {$O+} kapcsolót általában együtt használjuk a {$F+} kapcsolóval, hisz az overlay-kezelő mindig távoli (far) hívásokat használ. $R - Értéktartomány ellenőrzése (5.0) Alapértelmezés: {$R-} Típus : lokális Az értéktartomány-ellenőrzéséhez szükséges kódrészlet generálását engedé-lyezhetjük vagy tilthatjuk a fordító számára. {$R+} állapot: Bekapcsolt {$R+} állapotban végbemenő ellenőrzések: - tömb és sztring indexhatárainak ellenőrzése, - sorszámozott típusra vonatkozó értékadás esetén az értéktartomány ellenőrzése, - virtuális metódus hívásakor a VMT meglétének ellenőrzése. Ha az ellenőrzés hibát észlel, a program run-time hibaüzenettel leáll. $S - Verem túlcsordulásának ellenőrzése (5.0) Alapértelmezés: {$S+} Típus : lokális Engedélyezhetjük vagy tilthatjuk a verem túlcsordulásának ellenőrzésére szolgáló kódrészlet generálását {$S+} állapot: Bekapcsolt {$S+} állapotban a fordító minden eljárás és függvény elején kódot helyez el, amely ellenőrzi, hogy elegendő veremterület áll-e rendelkezésre a lokális változók és más ideiglenes tárterületek létrehozására. Ha nem elég a terület a stack-en, akkor rutinhíváskor a program futása run-time hibaüzenettel megszakad. Az {$S-} állapotban, ha nincs elegendő hely a veremben, a rendszer összeomolhat. $V - Sztring típusú változó paraméterek ellenőrzése (5.0) Alapértelmezés: {$V+} Típus : lokális Bekapcsolt {$V+} állapotban a fordító ellenőrzi, hogy a sztring típusú formális és aktuális változó (var) paraméterek típusa megegyezik-e. Kikapcsolt {$V-} állapotban tetszőleges hosszú sztring típusú aktuális paraméter átadható, még akkor is, ha a formális paraméter maximális hossza nem egyezik meg az aktuális paraméter hosszával. $X - Kibővített Turbo Pascal szintaxis (6.0) Alapértelmezés: {$X-} Típus : globális Az $X kapcsoló segítségével engedélyezhetjük, vagy tilthatjuk a fordító számára a kibővített Turbo Pascal szintaxis használatát. Alaphelyzetben a kapcsoló kikapcsolt állapotban van, így a kibővített szintaxis használata fordítási hibához vezet. {$X+} állapot: Ebben az állapotban adott a lehetőség a függvények utasításként történő (eljárás-szerű) meghívására. Ekkor a függvények visszatérési értékét a rendszer nem dolgozza fel. A {$X+} direktíva nem érvényes a beépített függvényekre (függvényekre a SYSTEM unit-ban). F4.2. Paraméter direktívák A paraméter direktívák használatakor a direktíva nevét és a paraméterét legalább egy szóköznek kell elválasztania. Pl.: {$I TYPES.INC} {$O MOONUNIT.TPU} {$I File-név} - Forrásállomány beépítése (5.0) Típus : lokális A fordító a megadott forrásállomány tartalmát beépíti a direktíva helyére. Az alapértelmezés szerinti kiterjesztés .PAS. Az állományok maximálisan 15 szint mélységig ágyazhatók egymásba. Az include file nem képezheti utasításnak a részét, ezért a blokkutasítást (begin ... end) is teljes egészében tartalmaznia kell a file-nak. {$L File-név} - Tárgykódú (object) file beszerkesztése (5.0) Tipus : lokális A direktíva utasítja a fordítót, hogy az adott nevű tárgykódú file-t összeszerkessze az éppen fordított programmal vagy unit-tal. Ezt a direktívát assembly nyelven megírt external alprogramok kódba való beépítésére használjuk. A megadott file ún. Intel relokálható tárgykódú file (object file, .OBJ file) kell legyen. Az alapértelmezés szerinti kiterjesztés .OBJ. {$M veremméret, heapmin, heapmax} - A program memóriafoglalása (5.0) Alapértelmezés: {$M 16384,0,655360} Típus : globális A direktíva program indításakor lezajló memóriafoglalást definiálja. Segítségével beállíthatjuk a verem méretét (1024..65520), a heap méretének alsó határát (0..655360) és a heap mértének felső határát (heapmin..655360). A direktíva unit fordításakor nem fejti ki hatását. {$O Unit-név} - Overlay-struktúra kialakítása (5.0) Típus : lokális A direktíva hatására a fordító overlay-file-ba (.OVR) szervezi az így megadott unit-okat, amelyeket előzőleg a {$O+} kapcsoló direktívával fordítottunk le. A {$O unit-név} dírektívákat közvetlenül a program uses utasítása után kell elhelyeznünk. A direktíva nincs hatással unit-ok fordí-tására. F4.3. Feltételes fordítás A Turbo Pascal feltételes fordítási direktívái lehetővé teszik, hogy egy forrás file-ból a feltételes szimbólumok használatával különbőző kódokat generál-hassunk. Ehhez a Turbo Pascal rendelkezik néhány, az if utasításra hasonlító szerkezettel: {$IFxxx} .I.. {$ENDIF} vagy {$IFxxx} .I.. {$ELSE} .H.. {ENDIF} Az I. részben elhelyezkedő programsorokat akkor fordítja a fordító, ha a feltétel igaz, míg a H. részt hamis feltétel mellett dolgozza fel. Nézzünk néhány példát a feltételes fordítási szerkezetekre: {Ha a Debug szimbólum definiált, kiírja az a változó értékét} {$IFDEF Debug} writeln('a=',a); {$ENDIF} {Ha van 8087 a rendszerben a real helyett double típust használunk, ha nincs, minden valós típus real lesz. } {$IFDEF CPU87} {$N+} type real = double; {$ELSE} {$N-} type single = real; double = real; extended = real; {$ENDIF} F4.3.1 Feltételes szimbólumok A feltételes fordítás vezérlése a feltételes szimbólumok felhasználásával történik. Feltételes szimbólumokat a következő módszerek valamelyikével definiálhatunk: - használva a {$DEFINE szimbólum} és a {$UNDEF szimbólum} direktívákat, - a parancssor fordítónál a /D kapcsolóval megadva, - az IDE fordítónál az Options/Compiler menü Conditional Defines input sorába beírva. A feltételes szimbólumokra is a Pascal azonosítókra használt megkötések érvényesek. A Turbo Pascal az alábbi szabványos feltételes szimbólumokat definiálja: VER50 VER55 VER60 - mindig definiált, jelzi a fordító verziószámát MSDOS - mindig definiált, jelzi hogy az operációs rendszer MS-DOS vagy PC-DOC CPU86 - mindig definiált, jelzi hogy a processzor 80x86 CPU87 - definiált, ha a fordítási időben van a gépben 80x87 társ- processzor F4.3.2. Feltételes direktívák {$DEFINE név} Feltételes szimbólum definiálása megadott névvel. Ha az adott névvel már létezik szimbólum, nincs hatása a direktívának. {$UNDEF név} Előzőleg definiált szimbólumot definiálatlanná tesz. Ha a szimbólum még nem definiált, nincs hatása. {$IFDEF név} A direktíva után álló forrássorokat lefordítja a fordító, ha az adott nevű szimbólumot előzőleg definiáltuk. {$IFNDEF név} A direktíva után álló forrássorokat lefordítja a fordító, ha az adott nevű szimbólumot előzőleg még nem definiáltuk. {$IFOPT kapcsoló} Ha az adott kapcsoló a megadott állapotban van, a fordító elvégzi a direktívát követő sorok fordítását. Például akkor lesz real típusból extended, ha az $N kapcsoló aktív: {$IFOPT N+} type real=extended; {$ENDIF} {$ELSE} Az {$INDEF}, {$IFNDEF}, {$IFOPT} és a {$ENDIF} között használható a hamis ág kijelölésére. {$ENDIF} Az utolsó {$IFxxx} feltételes direktívához tartozó programrészlet végét jelöli.