Dyrektywa kompilatora

Dyrektywa kompilatora – zawarte w tekście kodu źródłowego polecenie dla translatora, wykonania określonej czynności, lub ustalające sposób translacji. Dyrektywy kompilatora nie są częścią języka programowania, lecz jego standardu bądź konkretnej implementacji.

Sposób zapisu

Ponieważ dyrektywy kompilatora nie są częścią języka programowania, muszą być zapisywane w kodzie źródłowym w taki sposób, aby translator mógł odróżnić i wyodrębnić dyrektywę, z tekstu zapisanego w swej zasadniczej części w określonym języku źródłowym. Typowym rozwiązaniem jest zapis dyrektyw w kompilatora w formie komentarza o specyficznej składni. W zasadzie zespół zdefiniowanych dyrektyw stanowi również sam w sobie pewien język skryptowy sterowania translacją.

Pascal

Przykładowo w języku Pascal[1] i większości jego implementacji (np. Turbo Pascal[2]) oraz Object Pascal i jego implementacji[3][4][5] (np. Delphi, Free Pascal/Lazarus) zapis dyrektyw kompilatora ma jedną z postaci:

  • {$dyrektywa}
  • {$dyrektywa parametry}
  • {$lista_dyrektyw_przełącznikowych}

Jak widać dyrektywa stanowi komentarz, w którym pierwszy znak $ odróżnia zwykły komentarz, od dyrektywy kompilatora. Taki sposób zapisu zapewnia, że kod źródłowy zapisany w danym języku, przeniesiony do implementacji, w której nie występowałby taki zestaw dyrektyw kompilatora, będzie mógł być uruchamiany, gdyż komentarze będę ignorowane. Parametry występują tylko w pewnych dyrektywach, w prostych przypadkach dyrektywy do pojedyncze polecenia.

Poszczególne dyrektywy są identyfikowane zwykle:

  • pojedynczym znakiem, np. {$I proc1.pas}
  • zestawem znak i symbol, np. {$R+}
  • słowem kluczowym, np. {$IFDEF WINDOWS}

PL/M

W języku PL/M-80[6] opcje kompilacji mogą być umieszczane w kodzie źródłowym, wyłącznie w oddzielnych wierszach (oddzielnych od wierszy zawierających kod w języku PL/M). Wiersz taki identyfikowany jest znakiem dolara $ umieszczonym w pierwszej kolumnie danego wiersza (pierwszy znak wiersza), po którym może wystąpić lista dyrektyw kompilatora, rozdzielonych spacjami. Dyrektywy identyfikowane są słowami, np. PAGING, PRINT(n), PAGEWIDTH(w), DEBUG, INCLUDE(n) itp..

Rozróżnia się:

główne opcje kompilacji
dyrektywy je identyfikujące mogą być umieszczane w tekście kodu źródłowego tylko przed pierwszym wierszem zawierającym kod w języku PL/M,
poboczne opcje kompilacji
odpowiednie dyrektywy mogą występować w dowolnym wierszy pomiędzy wierszami kodu w języku PL/M.

Rodzaje dyrektyw

Ogólnie, można wyróżnić dyrektywy:

definiujące
taka dyrektywa definiuje pewną stałą, która umożliwia parametryzowanie kompilacji, poprzez kontrolę istnienia definicji w dyrektywach warunkowych, np. DEFINE, UNDEF
parametryczne
które przekazują informację do translatora, informacje te mogą dotyczyć środowiska, w którym następuje kompilacja, dostępność pamięci, zbiór, który ma być włączony do kodu źródłowego, np. C atrybuty, I nazwa_zbioru,
warunkowe
umożliwiającą kompilację warunkową określonych sekcji kodu źródłowego (sekcja rozumiana jest jako tekst zawarty pomiędzy dyrektywą warunkową a dyrektywą zamykającą blok dyrektywy warunkowej, porównaj: instrukcja warunkowa), może to dotyczyć np. uwzględnienia różnic systemów komputerowych i wiele innych zastosowań, np. IFDEF nazwa, IFNDEF nazwa, IFOPT przełącznik, ELSE, ENDIF,
przełącznikowe
ustalające sposób kompilacji, sposób ten może być różny dla różnych, nawet niewielkich fragmentów kodu, np. F+, F-, S+, S- i inne.

Podział dyrektyw

Można wyróżnić:

dyrektywa globalna
jej działanie odnosi się do całości kodu, a w zasadzie jednostki samodzielnie kompilowanej (program, moduł, biblioteka itp.), musi więc być umieszczona na początku tekstu źródłowego podlegającego przetwarzaniu, taka dyrektywa może być zastąpiona parametrem wywołania, programem pomocniczym, opcjami systemu okienkowego czy komendą języka systemu operacyjnego (patrz dalej)
dyrektywa lokalna
jej działanie następuje w konkretnym miejscu, można nazwać taką dyrektywę poleceniem lub instrukcją dla translatora, ma odniesienie do wybranego fragmentu kodu, może występować w dowolnej części kodu źródłowego (np. dyrektywy warunkowe, definiujące czy niektóre dyrektywy przełącznikowe).

Stałe

Stałe definiuje się w celu późniejszej parametryzacji kompilacji za pomocą dyrektyw warunkowych. Do definicji stałych służą dyrektywy definiujące. Stałe definiowane są przez programistę w konkretnym zbiorze kodu źródłowego. Taka stała może służyć następnie do sprawdzenia w innej jednostce, czy dany zbiór został włączony do kodu, a tym samym czy zadeklarowane i definiowane w tym zbiorze elementy kodu są dostępne w kompilowanym programie.

Innym rodzajem stałych, są stałe predefiniowane przez system programowania. Są to głównie stałe określające bieżący system komputerowy, lub system docelowy, dla którego ma nastąpić kompilacja (np. przy kompilacji skrośnej), a także szczegóły środowiska i dostępu do składowych tego środowiska oraz identyfikujące ten system.

Przykładowe stałe predefiniowane dla systemu Turbo/Borland Pascal w środowisku DOS/Windows: VER70 (lub inna), MSDOS, WINDOWS, CPU87 itp.[2].

Porównanie z innymi rozwiązaniami

Stosowanie dyrektyw kompilatora, to jedno z kilku rozwiązań, które może być zastosowane do sterowania kompilacją przez autorów systemów programowa. Ponadto w danej implantacji, może być dostępnych kilka rozwiązań równocześnie, alternatywnie lub uzupełniająco.

Dyrektywy a preprocesor

Zasadnicza różnica pomiędzy dyrektywami kompilatora a preprocesorem polega na tym, że:

  • dyrektywy przetwarza translator podczas kompilacji
  • preprocesor przekształca tekst kodu źródłowego przed kompilacją.

Z dostępnych w praktyce systemach programowania, można zaważyć dużo większe możliwości preprocesorów (np. język C[7], C++[8]), w porównaniu do dyrektyw (np. Pascal). Przede wszystkim to możliwość typowych preprocesorów w zakresie definiowania parametryzowanych makr i stałych preprocesora z określoną wartością, która może zostać wykorzystana w kodzie źródłowym, a nie tylko w samym preprocesorze. Największą przewagę wykazują bardziej rozbudowane preprocesory, np. Clipper[9], PL/I[10].

Dyrektywy a instrukcje

Niektóre czynności lub parametry dla kompilacji, wyłączone w większości języków programowania do implementacji (dyrektyw, preprocesora lub innych rozwiązań), w pewnych językach mogą zostać włączone do składni języka, jako jego integralna część. Te polecenia, nazywane w nomenklaturze tych języków, tak samo jak pozostałe jednostki, np. instrukcjami, w istocie swej (lecz nie w składni i nazewnictwie wykreowanym w dokumentacji i literaturze przedmiotu), są dyrektywami dla translatora.

Przykładem jest język Visual Basic, w którym ustawienia kompilacji są definiowane w specjalnych instrukcjach tego języka, np. OPTION BASE 1.

Dyrektywy a parametry wywołania

Dyrektywy globalne (tj. dotyczące całego kodu źródłowego) kompilatora, mogą mieć lub być zastąpione parametrami wywołania translatora. Dotyczy to głównie tych translatorów, które pracują w systemach opartych na konsoli i są wywoływane w wierszu poleceń z odpowiednimi argumentami. Zestaw takich parametrów jest jednak ograniczony do opcji dla całego kodu, i tym samym mniejszy niż zestaw dyrektyw kompilatora.

Dyrektywy a programy pomocnicze

Część pakietów programistycznych udostępnia pewne programy pomocnicze, pomocne przy kompilacji i łączenia wygenerowanego kodu, szczególnie dla większych projektów. Taki program uwzględniać może parametry wywołania lecz występują tu te same ograniczenia co przy parametrach wywołania.

Przykładem jest program Make stanowiący część pakietów serii Turbo, np. Turbo/Borland Pascal[2].

Dyrektywy a system programowania

W okienkowych systemach programowania, zarówno pracujących w trybie tekstowym (np. systemy serii Turbo), czy okienkowych (np. w systemie Windows), parametry kompilacji dostępne za pomocą dyrektyw, mogą być również ustawiane za pomocą poleceń i pól edycyjnych czy wyboru, dostępnych w menu tych systemów lub paskach przycisków uruchamiających specjale okienka dialogowe z opcjami do ustawienia. Ten sposób tak jak parametry jest ograniczony do konkretnej jednostki kompilowanej samodzielnie (niezależnie), np. modułu. Tylko od autorów aplikacji okienkowej zależy czy wszystkie opcji globalne kompilacji dostępne za pomocą dyrektyw będą miały swoje odpowiedniki w poleceniach menu i okienkach dialogowych.

Dyrektywy a komendy systemu

Takie rozwiązanie parametryzacji kompilacji dostępne było w starszych, oblecenie już nie stosowanych systemach, zawierających specjalny język komunikacji z operatorem, np. JCL[10]. W języku tym zawarte mogą być polecenia zastępujące dyrektywy kompilatorów i to dostępne dla różnych języków programowania.

Dyrektywy asemblera

Dyrektywy asemblera są w zasadzie tym samym co dyrektywy kompilatora, dostosowane jednak do specyfiki języka niskiego poziomu. Przykładowymi dyrektywami dla asemblerów rodziny procesorów serii x86[11]:

  • dyrektywy danych (np. DB, DW, SEGMENT itd.)
  • dyrektywy wydruku (np. PAGE, TITLE itd.)
  • dyrektywy trybu (np. .286!C itd.).

Zobacz też

Przypisy

  1. Michał Iglewski, Jan Madey, Stanisław Matwin, Pascal. Język wzorcowy – Pascal 360., Wydawnictwa Naukowo-Techniczne, Warszawa 1984, wydanie trzecie – zmienione, Seria: Biblioteka Inżynierii Oprogramowania, ISBN 83-204-0597-1
  2. a b c Andrzej Marciniak, Borland Pascal 7.0, Wyd. Nakom, Poznań 1994 r., ISBN 83-85060-53-7, ISSN 0867-6011
  3. Global compiler directives | Free Pascal and Lazarus Wiki. wiki.lazarus.freepascal.org. [dostęp 2021-04-23]. (ang.).
  4. Local compiler directives | Free Pascal and Lazarus Wiki. wiki.lazarus.freepascal.org. [dostęp 2021-04-23]. (ang.).
  5. Delphi Compiler Directives (List) Index | Embarcadero Docwiki. docwiki.embarcadero.com/RADStudio/Sydney/en/Main_Page. [dostęp 2021-04-23]. (ang.).
  6. Jan Bielecki, PL/M język programowania mikroprocesorów, Wydawnictwa Komunikacji i Łączności, Warszawa 1987, Seria: Elektronizacja, zeszyt 25
  7. Jan Bielecki, Turbo C z grafiką na IBM PC, Wydawnictwa Naukowo-Techniczne, Warszawa 1990, Seria: Mikrokomputery, ISBN 83-204-1101-7
  8. Jan Bielecki, Od C do C++, programowanie obiektowe w języku C, Wydawnictwa Naukowo-Techniczne, Warszawa 1990, ISBN 83-204-1332-X
  9. Wojciech Rogowski, Arkadiusz Serodziński, Clipper 5.0, Warszawa: Wydawnictwo PLJ, 1991, ISBN 83-85190-20-1, OCLC 749775734.
  10. a b Jan Bielecki, Rozszerzony PL/I i JCL w systemie OS/RIAD, Państwowe Wydawnictwo Naukowe, Warszawa 1986, Seria: Biblioteka Informatyki, ISBN 83-01-06146-4
  11. Leo J. Scanlon, Assembler 8086/8088/80286, Intersoftland, Warszawa 1992, tłumaczenie: Lucyna Stanikowska, ISBN 83-85515-03-8