Fordítási direktívák

A Free Pascal-ban - hasonlóan a Turbo Pascal-hoz - a fordítási direktívák vontakozási/érvényességi körüket tekintve két nagy csoportba oszthatók. Az első csoportot a globális direktívák alkotják, melyek jellegükből adódóan az egész modulra és/vagy a teljes fordítási ciklusra kiterjedő beállításokat szabályozzák. Ilyen jellemzők például a nyomkövetési információk generálása, a matematikai koprocesszor alkalmazása vagy a célprocesszor és ezen keresztül a kódgenerálás során alkalmazott utasításkészlet meghatározása. Ezen beállításokat mindig a modul/program első utasítása előtt kell meghatároznunk és nincs lehetőség utólagos, a modul későbbi részeiben történő módosításukra. A globális direktívák egy része csak a főprogramban szerepeltetve nyer jelentőséget - ilyen beállítás például a futás során használt memória-területek (heap, stack) mérete. Más globális direktívák - mint például a verem-ellenőrzés (stack-checking) - ezzel szemben bármelyik modulban megadhatók.

A fordítási direktívák másik, általában nagyobb csoportját alkotják az ún. lokális direktívák, melyeknek közös jellemzője, hogy a modulon belül is többször ki-/bekapcsolhatók, mert kizárólag olyan jellemzőket határoznak meg amelyek a globális kódgenerálást nem befolyásolják. A lokális direktívák közé tartoznak például a változók/adatok szó-határra igazítását (align) befolyásoló, vagy a ki-/beviteli műveletek sikerességének ellenőrzését (I/O checking) szabályozó kapcsolók.

A Turbo Pascal-hoz hasonlóan a Free Pascal is támogatja az ún. feltételes fordítási direktívák használatát, melyek segítségével bizonyos kódrészletek feldolgozását/fordítását meghatározott körülményektől tehetjük függővé. Az eredeti változathoz képest azonban a definiáltság lekérdezése során nem csak egyetlen, konkrét direktíva létezése vizsgálható, hanem több részből álló, logikai operátorokkal és relációkkal összekapcsolt, komplex kifejezés vizsgálata is megadható.

A fent említett három csoporton kívül azonban a Free Pascal egy negyedik típusú direktíva-csoportot, ún. üzenet-direktívákat is rendelkezésünkre bocsát. E speciális direktívák segítségével lehetőségünk nyílik a forráskód bizonyos részeinek feldolgozása során üzenetek, hibakódok közlésére a programot fordító felhasználó felé, a Free Pascal által küldött üzenetekhez, figyelmeztetésekhez hasonló módon.

Az alkalmazható fordítási direktívák felsorolását és funkcióik leírását a Free Pascal Programmer's manual tartalmazza.

Makrók

A Free Pascal az eredeti nyelv bővítéseként a C-ből jól ismert kód-makrók alkalmazásának lehetőségét is rendelkezésünkre bocsátja. A makrók gyakran alkalmazott, ismétlődő kódrészletek vagy deklarációk ismételt beírásától kímél meg minket, egy funkcióhívás nélküli formát alkalmazva. Ha a fordító a forráskód feldolgozása során definiált makró-azonosítóra bukkan, azt először kicseréli a definiált makró-tartalomra, majd ezt értelmezve folytatja az állomány feldolgozását. Ez gyakorlatilag azt jelenti, hogy a makrók deklarációinak feldolgozása során - más nyelvi elemekkel szemben - nem, csak a feldolgozás (referencia) helyén jutnak szemantikai tartalomhoz. A kibontott makró-hivatkozásokat a fordító ugyanúgy kezeli mintha azok már eleve a forráskódban szerepeltek volna, azaz a bennük található esetleges makró-hivatkozásokat is folyamatosan, rekurzív módon kibontja. (Ez utóbbi miatt érdemes a makró-deklarációkkal vigyázni, ugyanis így végtelen fordítási ciklust előidéző rekurzív szerkezetek is létrehozhatóak.)

Támogatott adattípusok és -szerkezetek

A Free Pascal az előre definiált elemi adattípusok terén a kompatibilitás megőrzését, míg a támogatott adatszerkezetek esetén a célszerűség és a programozás-technikai újdonságok felhasználását teszi lehetővé. Az előre definiált elemi egész típusok neveit és jellemzőit az alábbi táblázat tartalmazza:
 
 

Típus neve
Tárolható 
érték-intervallum
Méret (bájtokban)
Byte
0..255
1
Shortint
-128..127
1
Integer
-32768..32767
2
Word
0..65536
2
Longint
-2,147,483,648..
2,147,483,647
4
Cardinal
0..4,294,967,296
4

A fordító a különböző egész típusok közti konverziót automatikusan elvégzi, de amennyiben ennek során a cél-változón nem tárolható eredményt kap - és amennyiben ennek vizsgálatát (range-checking) szabályozó fordítási be van kapcsolva - úgy ez esetben futásidejű hibát generál. A Free Pascal a Turbo Pascal-hoz hasonlóan a "$" prefix használatával lehetővé teszi hexadecimális konstans-értékek definiálását, valamint külön bővítésként immár az assembly nyelvű betéteken kívül is alkalmazhatunk bináris formában megadott számokat a "%" segítségével.

A Free Pascal a lebegőpontos műveletek elvégzését teljes egészében a matematikai társprocesszorra (vagy annak hiánya esetén a koprocesszor-emulátorra) bízza. Ennek megfelelően lebegőpontos elemi adat-típusai megegyeznek a koprocesszor által támogatott belső formátumokkal és ábrázolási tartományokkal és így bináris szinten inkompatibilisek a Turbo Pascal azonos nevű megfelelőivel. A fordító által definiált lebegőpontos adattípusok neveit és jellemzőit az alábbi táblázat tartalmazza:
 

Típus neve
Tárolható érték-intervallum
Értékes jegyek száma
Méret (bájtokban)
Single
1.5E-45..3.4E38
7-8
4
Real
5.0E-324..1.7E308
15-16
8
Double
5.0E-324..1.7E308
15-16
8
Extended
1.9E-4951..1.1E4932
19-20
10
Comp
-2E64..2E64-1
19-20
8

A comp egy speciális, lebegőpontosnak minősülő, de csak egész értékeket tároló típus - kezelése megegyezik a Turbo Pascal azonos nevű típusáéval. Ugyancsak érdemes észrevenni, hogy a Real és Double típusok teljesen identikusak: valójában a fordító minden real típusúnak deklarált változót és mezőt automatikusan Double típusúnak tekint.

A sztringek kezelésének területén a Free Pascal a Delphi számos újítását átvéve, valamint néhány saját bővítést hozzáadva meglehetős változásokat hoz a Turbo Pascal-hoz képest. A fordító által ismert sztring-alaptípusokat és jellemzőiket az alábbi táblázat foglalja össze:
 

Típus neve
Maximális hossz (kar.)
Méret a memóriában (bájt)
Memória-foglalás módja
Shortstring
255
1 + <max. hossz> 
Statikus
Ansistring
>2 milliárd
8 + <akt. hossz>
Dinamikus
Widestring
>1 milliárd
8 + <akt. hossz>*2
Dinamikus

Mint az a fenti táblázatból kitűnik, a standard Pascal "string" típusának a Free Pascal shortstring nevű elemi típusa felel meg. A másik két sztring-típus alkotja az ún. longstring-ek (hosszú stringek) csoportját, melyek elméletileg 2GB hosszúságúak is lehetnek. A Widestring minden egyes eleme - szemben a másik két típussal - nem 1, hanem 2 bájt méretű - ez a karaketerenként 16-bites ábrázolási mód lehetővé teszi az összes létező nyelv írásjeleit egyértelműen azonosító, ún. Unicode karakter-kódok használatát.

Azt, hogy "string" típusúnak deklarált változókat/mezőket a fordító milyen elemi típusúnak tekinti a {$H} fordítási kapcsoló határozza meg: kikapcsolt állapot esetén a szóban forgó típust a Turbo Pascal-lal kompatíbilis módon Shortstring típusúnak, míg bekapcsolt fordítási direktíva esetén Ansistring típusként értelmezi.

A logikai változók területén a Free Pascal szintén a Delphi-kompatibilitásra törekszik. Ennek megfelelően három elemi logikai típust definiál. Az elemi logikai típusokat és jellemzőiket az alábbi táblázat tartalmazza:
 

Típus neve
Méret (bájt)
Boolean
1
Wordbool
2
Longbool
4

A sztringekkel szemben az elemi logikai típusok értelmezése teljes egészében megegyezik: a 0 decimális értéket tartalmazó változók és mezők logikai értéke hamis (false), míg az ettől eltérő értékűeké igaz (true). Különbség közöttük mindössze az elfoglalt tárterület méretében mutatkozik - ennek azonban csakis szigorúan technikai okai vannak. Fontos megjegyezni, hogy a logikai kifejezések kiértékelését a Free Pascal csakis addig végzi, amíg annak szerkezetéből és a kapott részeredményekből egyértelműen ki nem deríthető a kifejezés értéke. Ezt az ún. short-cut evaluation módszert lehetett felülbírálni a Turbo Pascal-ban a {$B+} direktíva, az ún. complete boolean evaluation (teljes boolean-kiértékelés) bekapcsolásával - erre Free Pascal alatt nincs mód.

A tömbök tekintetében a Free Pascal teljesen kompatíbilis a Turbo Pascal-lal: használatával tetszőleges dimenziós tömbök is létrehozhatóak. Bár a fordító aktuális verziója még nem támogatja a Delphi dinamikus tömbjeinek használatát, de a tömb méretét ahhoz hasonlóan ez esetben is csak a rendelkezésre álló memória korlátozza (tehát 64kb-nál nagyobb tömbök is definiálhatók).
 

példa a C-stílusú tipizált-pointerekre:

program PointerArray;

var i  : longint;
    p  : ^longint;
    pp : array[0..100] of longint; 

begin
  for i:=0 to 100 do pp[i]:=i; { Tömb feltöltése }
  p:=@pp[0];           { p mutasson pp-re }
  for i:=0 to 100 do
    if p[i]<>pp[i] then
      writeln ('Ez nem lehet !';)
end.

A Free Pascal-ban definiált pointer-típusok az alkalmazott 32-bites memória-szerkezethez igazodnak. A hagyományos programon belüli használatra a Free Pascal a Turbo Pascal-hoz hasonlóan egy 4 bájt méretű pointer nevű típust definiál. Ez a mutató azonban nem szegmens-offszet párosból, hanem mindössze egyetlen 32-bites offszet-értékből áll, és a program adatszegmensén belüli tetszőleges pontra mutathat. Ezen kívül a fordító definiál egy farpointer típust is, amely a 32-bites offszett érték mellett egy 16-bites szelektor-értéket is eltárol - az ilyen típusú változók használhatók a más, a programon kívüli szegmensekbe irányuló hivatkozások tárolására. A fordító ezek mellett támogatja a mutatókon végzett C-típusú pointer-operációkat (egy tipizált pointer tekinthető és hivatkozható, mint egy megegyező típusú elemekből álló tömb első eleme), valamint a pointer-aritmetikát (a mutató értéke bármilyen egész típushoz hasonlóan egyszerűen növelhető ill. csökkenthető egész számokkal).

Type TFuncType = Function (Var X : integer): boolean; 
var Func : TFuncType;

Function IsOdd(Var X: integer): boolean;
Begin
  ..
  ..
end;
...

Func:=@IsOdd;
...

Az ún. eljárás-változók a Turbo Pascal-hoz hasonlóan itt is megtalálhatóak (procedural variables), azonban - az egyértelműség miatt - értékadás (:=) esetén szükséges a @ operátor használatára.

A következő két deklaráció:

Type
       {$PACKRECORDS 1}
        TRecord = Record
          A : Byte;
          B : Word;
        end;
és
       {$PACKRECORDS 2}
        TRecord = Packed Record
          A : Byte;
          B : Word;
        end;

bináris megjelenésében teljesen egyenértékű.

A rekordok kezelésének területén szintén nem hoz sok újítást a Free Pascal: támogatja a hagyományos, egymásba ágyazott, illetve feltételes rekord-szerkezeteket is. Fontos azonban megjegyezni, hogy az optimalizáció során - ha a {$PACKRECORDS} direktívával másként nem rendelkezünk - a fordító a futási sebesség növelése érdekében minden rekord-mezőt 4-bájtos határra igazít. Így, amennyiben a Turbo Pascal-lal binárisan kompatíbilis rekord-szerkezeteket szeretnénk, úgy anak léterehozására a record előtti packed kulcsszó használatával utasíthatjuk a fordítot - ez esetben az a rekord mezőit folytonosan, szigorúan csak a tárolásukhoz szükséges terület fenntartásával illeszti egymás után (azaz minden mezőt bájt-igazítottan helyez el).

Type

EnumType = (Elso, Masodik, Harmadik, Negyedik:=20, Otodik);

A fenti példában az elemeknek ordinális értékei rendre 0,1,2,20 ill. 21.

A típus-készletek (set) területén a fordító a Turbo Pascal-hoz hasonlóan használható. A 32-nél nem több elemet tartalmazó set-eket a program egyetlen longint-ben, míg az ettől eltérű elemszámúakat egy 32-bájtos tömbben tárolja. A már megszokott set-operátorok (+,-,*) természetesen itt is használhatóak.

Az enumerált típusok kezelése szintén megegyezik a megszokottal, azzal az apró eltéréssel, hogy méretük bájt helyett longint. Ezen kívül lehetőség van az enumerált elemekhez rendelt numerikus értékek (az ún. ordinal values) kiosztásának megváltoztatására, azaz, bizonyos értékek "kihagyásával" is definiálhatunk típusokat. Ez utóbbi bővítés alkalmazása esetén azonban természetszerűen nem használhatók a típussal kapcsolatban a pred() ill. succ() függvények, hiszen az elemek nem alkotnak folyamatos intervallumot.