Mendelova univerzita v Brně Provozně ekonomická fakulta
Schopnosti překladačů vybraných strukturovaných jazyků Diplomová práce
Vedoucí práce: Ing. Pavel Haluza
Bc. Stratos Zerdaloglu
Brno 2012
2
Na tomto místě bych chtěl poděkovat Ing. Pavlu Haluzovi za vedení diplomové práce a cenné rady při její tvorbě.
4
Prohlašuji, že jsem tuto diplomovou práci vyřešil samostatně s použitím literatury, kterou uvádím v seznamu.
V Brně dne 23. května 2012
....................................................
6
7
Abstract Zerdaloglu, S. The abilities of compilers of selected structured languages. Diploma thesis. Brno, 2012. This thesis deals with analysis and capability testing of currently used compilers C and Pascal. Properties of compilers and their development environments were evaluated using properly selected and designed test samples. Features evaluated included time and memory demand, responses to various errors in source code or support for selected language elements. Results of individual tests were analyzed, commented, and clearly interpreted. Key words compiler, structured language, Pascal, testing samples, syntax error
Abstrakt Zerdaloglu, S. Schopnosti překladačů vybraných strukturovaných jazyků. Diplomová práce. Brno, 2012. Diplomová práce se zabývá analýzou a testováním schopností v současnosti používaných překladačů jazyka C a Pascal. Za pomoci vhodně vybraných a navržených testovacích vzorků je hodnocena řada vlastností překladačů a jejich vývojových prostředí. K hodnocením vlastnostem patří časová a paměťová náročnost, reakce na různé typy chyb ve zdrojovém kódě nebo podpora vybraných prvků jazyka. Výsledky jednotlivých testů jsou analyzovány, komentovány a přehledně interpretovány. Klíčová slova překladač, strukturovaný jazyk, Pascal, testovací vzorky, syntaktická chyba
8
9
OBSAH
Obsah 1 Úvod a cíl práce
11
2 Přehled literatury
12
3 Programování 13 3.1 Programovací paradigmata . . . . . . . . . . . . . . . . . . . . . . . . 13 3.2 Strukturované programovací jazyky . . . . . . . . . . . . . . . . . . . 16 3.3 Chyby v programech . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4 Překladače 4.1 Úvod do překladačů . . . . . . . . . . . . . . . . . . . . 4.2 Princip práce překladače . . . . . . . . . . . . . . . . . 4.3 Jazyk symbolických adres . . . . . . . . . . . . . . . . 4.4 Integrovaná vývojová prostředí . . . . . . . . . . . . . 4.5 Vybrané překladače a vývojová prostředí jazyka Pascal 4.6 Vybrané překladače a vývojová prostředí jazyka C . . . 4.7 Časová a prostorová složitost . . . . . . . . . . . . . . . 5 Testování vlastností překladačů 5.1 Testovací vzorky . . . . . . . . . . . 5.2 Hodnotící a porovnávací kritéria . . . 5.3 Využité nástroje a testovací prostředí 5.4 Syntaktické a sémantické chyby . . . 5.5 Běhové a logické chyby . . . . . . . . 5.6 Paměťová a časová náročnost . . . . 5.7 Efektivita strojového kódu . . . . . . 5.8 Dokumentace a podpora . . . . . . . 5.9 Specifika daného jazyka . . . . . . . 6 Shrnutí a interpretace výsledků 6.1 Časová a paměťová náročnost . . 6.2 Reakce na chyby . . . . . . . . . 6.3 Dokumentace . . . . . . . . . . . 6.4 Podpora vybraných prvků jazyka
. . . .
. . . .
. . . . . . . . .
. . . .
. . . . . . . . .
. . . .
. . . . . . . . .
. . . .
. . . . . . . . .
. . . .
. . . . . . . . .
. . . .
. . . . . . . . .
. . . .
. . . . . . . . .
. . . .
. . . . . . . . .
. . . .
. . . . . . . . .
. . . .
. . . . . . . . .
. . . .
. . . . . . .
. . . . . . . . .
. . . .
. . . . . . .
. . . . . . . . .
. . . .
. . . . . . .
. . . . . . . . .
. . . .
. . . . . . .
. . . . . . . . .
. . . .
. . . . . . .
. . . . . . . . .
. . . .
. . . . . . .
. . . . . . . . .
. . . .
. . . . . . .
. . . . . . . . .
. . . .
. . . . . . .
19 19 20 22 23 28 30 31
. . . . . . . . .
32 35 35 36 37 42 42 46 48 50
. . . .
52 52 57 57 58
7 Diskuse
59
8 Závěr
61
9 Literatura
62
10
OBSAH
1
1
ÚVOD A CÍL PRÁCE
11
Úvod a cíl práce
V dnešní době nám počítače stále více pomáhají usnadňovat a řešit úlohy z nejrůznějších oblastí našeho běžného života. Bez počítačů bychom se již velmi těžko obešli. Pomohou nám spočítat obtížné matematické problémy, dokáží uchovat takové množství dat, na jejichž zapamatování by nám nestačily ani tisíce našich životů. To vše nám zajistí potřebný software, bez kterého by počítač byl jen mrtvé železo. Naprostá většina softwaru je vytvořena pomocí jednoho z vyšších programovacích jazyků. Programovací nebo skriptovací jazyk je v současnosti jeden z nejpoužívanějších prostředků pro tvorbu algoritmů. Samotný programovací jazyk ale pro tvorbu výsledného programu nestačí, protože procesor počítače vyšší programovací jazyk nedokáže přímo zpracovat. Procesor je schopný zpracovat pouze strojový kód, který lze definovat jako posloupnost instrukcí prováděných procesorem počítače. Programování přímo ve strojovém kódu je pracné a v praxi se již nepoužívá. Nevýhodou je zejména používání nepřehledných číselných kódů. Z toho důvodu se dnes pro tvorbu softwaru uplatňují vyšší programovací jazyky, které programátorovi ulehčí mnoho času. Překladače následně přeloží zdrojový kód do spustitelné podoby na dané platformě. Dnes existuje pro různé programovací jazyky a odlišné platformy řada překladačů, které se od sebe liší různými vlastnostmi. Zejména různou podporou implementace daného programovacího jazyka. Pokud se věnujeme programování hlouběji, je znalost principů překladačů vhodná až nezbytná. Práce si klade za cíl analyzovat vlastnosti překladačů vybraných strukturovaných programovacích jazyků s důrazem na stanovení časové a prostorové složitosti. Snahou je zmapování možností současných překladačů strukturovaných programovacích jazyků z technického i uživatelského pohledu. Vlastnosti překladačů budou testovány na nejrůznějších vzorcích a algoritmech daného jazyka. Práce v určitém smyslu doplňuje obhájenou diplomovou práci Ing. Martina Ventruby, která se zabývala analýzou schopností překladačů objektově orientovaných programovacích jazyků (Ventruba, 2011).
12
2
2
PŘEHLED LITERATURY
Přehled literatury
Oblast překladačů a programovacích jazyků je velice široká, a tak k ní existuje velké množství literatury v českém nebo anglickém jazyce. Z kapitoly překladačů má svůj velký význam publikace Automata and Languages: Theory and Applications od profesora Alexandera Meduny, která poskytuje podrobné teoretické zázemí překladačů a formálních jazyků (Meduna, 2000). Z publikací napsaných v českém jazyce určitě stojí za zmínku kvalitní skripta doktorky Šárky Vavrečkové ze Slezské univerzity v Opavě (Vavrečková, 2008), která obsahují čtivě a přehledně zpracovanou danou problematiku – zejména podrobné rozdělení překladačů. Překladačům se věnuje i rozsáhlý seriál o překladačích na portálu Abclinuxu (Vyskočil, 2006), který je k dispozici v elektronické podobě. Informace o konkrétních překladačích jsou dostupné zpravidla pouze na webových stránkách daných produktů. Starší, ale neméně kvalitní literaturou je kniha s názvem Kompilátory číslicových počítačů od Davida Griese (Gries, 2007). Kniha seznamuje čtenáře postupně s problematikou gramatik a jazyků a věnuje se také principům překladačů a jejich optimalizaci. Z oblasti programování a algoritmizace nelze vynechat několikasvazkové světoznámé dílo Umění programování od počítačového vědce Donalda Knutha (Knuth, 2008), který se zabývá algoritmy, matematickou analýzou a obecnou informatikou. Další potřebné teoretické podklady pro práci lze nalézt přímo v samotných publikacích programovacích jazyků. Cenné informace a podrobně popsaný jazyk C zahrnuje publikace Učebnice jazyka C od Pavla Herouta (Herout, 1981), která obsahuje podrobné kroky od základů přes pokročilé techniky v popsaném programovacím jazyku. Srovnáváním a hodnocením překladačů objektových programovacích jazyků se zabýval ve své diplomové práci Martin Ventruba (Ventruba, 2011). Komplexnější analýzou schopností překladačů strukturovaných programovacích jazyků se však žádná literatura příliš nezabývá. Problematiku srovnání dílčích částí překladačů řeší některé zahraniční elektronické vědecké publikace, které se zaměřují většinou pouze na konkrétní prvky překladačů, ale neřeší problematiku komplexněji.
3
PROGRAMOVÁNÍ
3
13
Programování
Programování je činnost, která zahrnuje návrh algoritmu, psaní zdrojového kódu, testování a údržbu softwarového díla. Algoritmus je základním pojmem a stavebním kamenem veškerého soudobého programování. Do roku 1950 bylo programování spojováno s Euklidovým algoritmem, který slouží ke zjištění největšího společného dělitele dvou čísel. Dnešní význam slova algoritmus je poněkud obecnější. Algoritmus je možno definovat jako konečnou množinu pravidel, které popisují posloupnost operací pro řešení určitého typu problému. Algoritmus musí splňovat několik důležitých vlastností: • konečnost, • určitost, • vstup, • výstup, • efektivita. Algoritmus musí skončit po konečném počtu kroků. Počet kroků může být libovolně velký, ale musí být konečný. Procedura, která tuto vlastnost porušuje, ale jinak odpovídá charakteristice algoritmu, se nazývá výpočetní metoda. Všechny kroky daného algoritmu musí být definovány a jeho operace jednoznačně popsány. Z toho důvodu se pro zápis algoritmu používají programovací jazyky, kde každý příkaz má jednoznačně definovaný význam. Vstupy jsou veličiny, které si algoritmus přebírá před vlastním zahájením z určené množiny objektů. Algoritmus může mít jeden nebo více výstupů. Výstupy lze opět označit jako veličiny, které mají zadaný vztah ke vstupům. Další podstatnou vlastností algoritmů je efektivita. Operace, které algoritmus provádí, by měly být v rozumné míře jednoduché. Problematikou efektivity algoritmů, tzn. metodami, jak z několika známých algoritmů řešících konkrétní problém vybrat ten nejlepší, se zabývají odvětví informatiky nazývané teorie složitosti. (Knuth, 2007)
3.1
Programovací paradigmata
Programovací paradigmata jsou vyzkoušené a ověřené techniky, které vedou k tvorbě kvalitního softwaru. Obsahují programovou strukturu a metodiku zpracování. Tedy jinými slovy, jakým způsobem dané dílo vytvořit co nejlépe a nejefektivněji. Naivní paradigma Naivní paradigma je nejčastěji používáno programátory začátečníky. Typickou charakteristickou vlastností je nekoncepčnost a chaotický způsob přístupu. Programovací jazyky, podporující naivní paradigma, jsou prakticky nestrukturované, nepodporují modularitu a též se vyznačují minimální datovou abstrakcí. Klasickým příkladem takového jazyka je programovací jazyk BASIC. (Skoupil, 1994)
14
3
PROGRAMOVÁNÍ
Funkcionální paradigma Funkcionální paradigma představuje na rozdíl od procedurálního paradigmatu princip v postupném aplikování funkcí. Nepoužívá se přiřazovací příkaz a jazyk je založen na funkcích a rekurzích. Funkcionální paradigma se vyjadřuje pomocí funkcionálních programovacích jazyků. Mezi nejznámější můžeme zařadit jazyk Lisp nebo Haskell. Tyto jazyky přistupují k programu obdobně jako k matematickému výrazu, který vyhodnocují deterministicky. Program nedisponuje žádným implicitním stavem a má pouze stavy explicitní. V programu nezáleží na tom, v jakém pořadí se jednotlivé příkazy provedou, ale pouze na dodržení daných závislostí. Funkcionální programovaní se vyznačuje vysokou mírou abstrakce a využívá se taktéž v umělé inteligenci. (Skoupil, 1994) Ukázka výpočtu faktoriálu: (defun fact (n) (if (zerop n) 1 (* n (fact (- n 1))))) Objektové paradigma Objektové paradigma je v současné době jeden z nejpoužívanějších přístupů vůbec. Základními kameny jsou prvky, které se nazývají objekty. Objekty modelují prvky reality. Každý objekt má uložen o sobě informace, které se definují jako atributy. Průběh výpočtu je uskutečňován jako zasílání zpráv mezi objekty. Abstrakce objektu, která zahrnuje podobné typy objektů, se nazývá třída (class). Typickými zástupci čistě objektových jazyků jsou Smalltalk, Java nebo Python. Řada moderních jazyků umožňuje kombinovat přístup strukturovaný a objektový, jako např. C++ nebo Java. (Skoupil, 1994) Základní vlastnosti objektů: • dědičnost, • polymorfismus, • zapouzdření. Ukázka návrhu třídy: class Konto { private: int cisloUctu; double stavKonta; public: void pridejCastku(double vklad); // definice veřejných metod void vyberCastku(double vyber); double vratStavKonta();
3.1
Programovací paradigmata
15
void prictiUroky(); ... }; Logické paradigma U logického paradigmatu je samotný program ve formě určité množiny pravidel, které se označují jako klauzule. Systém se na základě těchto klauzulí programu snaží dané tvrzení dokázat. Logické paradigma má velký význam zejména v oblasti umělé inteligence (znalostní systémy). Typickým zástupcem je jazyk Prolog. (Skoupil, 1994) Paralelní paradigma Paralelní paradigma je poměrné mladý způsob programování a rozvinul se zejména s nástupem více-procesových operačních systémů. Principem je dekompozice algoritmu na více úloh, které jsou zpracovávány souběžně odlišnými procesory. Paralelní programování má dnes uplatnění zejména v oblasti vědy a výzkumu. Důležitou součástí paralelního programování jsou vlákna. Dají se definovat jako lehčí varianta procesů a umožňují efektivněji využít systémové zdroje. Podporu paralelního programovaní najdeme např. u jazyků Java nebo C# (Skoupil, 1994). Procedurální paradigma Procedurální paradigma se někdy také označuje jako imperativní nebo klasické. Strukturovaný přístup používáme v životě při řešení úkolů a běžných životních situacích. Používání tohoto přístupu v těchto situacích je intuitivní a přirozené, takže se nad ním většinou nezamýšlíme. Například při hledání informací na internetu, vyhledávání informací v tištěném telefonním seznamu nebo jízdním řádu. Složitý problém si rozdělíme na menší části a činnosti vykonáváme postupně. To je podstatou strukturovaného přístupu. Popsaný přístup se uplatňuje ve strukturovaném programování. Strukturované programování je součástí imperativního programování, jehož typickými zástupci jsou jazyky C a Pascal. Počátek strukturovaného programování lze datovat vzniku článku z roku 1967, kterému se věnoval Edsger W. Dijkstra, který se zabýval odstraněním příkazem skoku (Goto) ve struktuře programu. Obecně lze strukturované programování definovat jako rozdělení algoritmu na dílčí úlohy, které jsou vykonávány postupně. Používají se vybrané řídicí struktury.
16
3
PROGRAMOVÁNÍ
Používané řídící struktury: • výběr – použití rozhodovacích příkazů, • sekvence – provádění příkazu postupně, tak jak jdou za sebou, • opakování – použití cyklů. Trendy v programování Existuje řada zarytých odpůrců a příznivců různých přístupů. Zejména mezi strukturovaným a objektovým programováním svádí příznivci každého z nich nelítostné názorové souboje. Ti konzervativnější uznávají pouze strukturovaný přístup, inovátoři zase spíše ten objektový. V současné době se nejvíce vyvíjí objektové programování v kombinaci s paralelním paradigmatem. Většina jazyků, které vznikly v pozdější době, jsou z drtivé části objektové. Samotné programování se nyní přibližuje více reálnému světu a je ulehčováno řadou automatizovaných nástrojů, takže programátor není nucen psát stále dokola ty samé kusy kódu. Moderní vývojová prostředí obsahují již řadu přednastavených šablon a knihoven, které stačí při tvorbě programu jen použít. To samozřejmě platí pro vývoj vysokoúrovňových uživatelských aplikací. Pro vývojáře operačních systémů, překladačů či tvorby knihoven, je stále nutná hluboká znalost programování a potřebných procesů. Na poli webových aplikací si v devadesátých letech prošly velkým rozmachem tzv. WYSIWYG editory, které dokázaly z návrhu vygenerovat kompletní HTML kód. Nejpopulárnější zástupce těchto programů byl MS Frontpage. Tyto editory ale generovaly velké množství kódu a to i nepotřebného, takže zdrojový kód stránky byl mnohokrát vyšší a obsahoval spoustu zbytečných značek. Za tyto vlastnosti, kterými disponovaly skoro všechny editory, byly často kritizovány. Běžným uživatelům však umožňovaly tvorbu webových stránek i bez znalosti značkovacích jazyků. V oblasti klasického vývoje aplikací se čím dál více uplatňuje vizuální programování, kde se při vývoji používá možností různých frameworků. Vkládáním obrázkových elementů a jejich úpravou lze částečně vytvořit potřebnou aplikaci a popřípadě doprogramovat další části kódu. Typickým zástupcem je programovací jazyk LabVIEW, který se používá pro vývoj testovacích, měřicích a řídících aplikací.
3.2
Strukturované programovací jazyky
Programovací jazyk Pascal Programovací jazyk Pascal je strukturovaný jazyk určený zejména pro výuku programování. V současné době se používá jeho objektová nástavba Object Pascal integrovaná do vývojového prostředí Delphi, které je určeno pro OS Windows. Dostal jméno podle známého francouzského filosofa, matematika a fyzika Blaise Pascala. Základy jazyka Pascal vznikly v roce 1970 a jeho autorem je Niklaus Wirth. (Moore, 2009)
3.2
Strukturované programovací jazyky
17
Byl založen na základě blokové struktury programovacího jazyku Algol. Cílem bylo nejen vytvořit programovací jazyk, který má přehlednou syntaxi a je tím pádem vhodný pro výukové účely, ale také aby byl prakticky použitelný na tehdejších počítačích. Standard jazyka Pascal byl zveřejněn v roce 1983 a je označován jako ISO 7185. Další významnou implementací je prostředí Turbo Pascal, který vylepšuje komfort původního standardu. Jazyk Pascal je silně typový strukturovaný programovací jazyk. (Moore, 2009) Programovací jazyk C Jazyk C byl vytvořen v Bellových laboratořích AT&T. Za autora tohoto jazyka je možné považovat Denise Ritchieho. Cílem bylo vytvořit jazyk pro snadnou a přenositelnou implementaci operačního systému Unix. Na vývoji jazyka se dále podíleli velkou měrou Brian Kernighan a Ken Thompson. (Rohovský, 2008) Za přímého předchůdce programovacího jazyka C je považován jazyk B, který vyvinul Ken Thompson. Uvažovalo se o něm původně jako o kandidátovi pro přepis Unixového jádra, ale tato možnost byla zamítnuta z důvodu malé rychlosti pro psaní jádra operačního systému. Měl také problémy s adresováním. (Rohovský, 2008) Jazyk C lze charakterizovat jako univerzální programovací jazyk nízké úrovně. Patří mezi imperativní jazyky. Má úsporné vyjadřování, je strukturovaný a disponuje velkým počtem operátorů. Jazyk C byl navržen a implementován v operačním systému UNIX, který je z velké části v C také napsán. První standard jazyka C pocházel od autorů Briana W. Kernigha a Denis M. Ritchie. Dnes se tento standard označuje jako K&R. Dalším standardem je ANSI C, který vznikl v roce 1988 a z předchozího standardu vychází. Definuje přesnou specifikaci množiny knihovních funkcí a hlavičkových souborů. Standard ANSI C podporuje naprostá většina současných kompilátorů. Na konci devadesátých let došlo k vydání dokumentu ISO 9899:1999 (obvykle nazývaný C99), který rozšiřuje původní standard ANSI C o některé další prvky. (Herout, 1981) Rozšíření jazyka C ve standardu C99: • on-line komentáře, • podpora dalších knihoven, • další datové typy – např. long long int, • variadická makra, • nové knihovní funkce, • klíčové slovo restrict. Vzhledem k univerzálnosti a přenositelnosti jazyka mezi různé architektury, není proto problém psát programy přenositelné na úrovni zdrojových kódů mezi různými Unixy a překladači. V jazyce C je napsána řada překladačů a systémových knihoven. V současné době se jazyk C uplatňuje právě pro vytváření nízkoúrovňových přenositelných programů, které absentují grafické uživatelské rozhraní (GUI).
18
3
PROGRAMOVÁNÍ
Pro tvorbu desktopových aplikací se dnes využívá zejména jazyk C++, který z jazyka C vychází a rozšiřuje ho hlavně o objektový přístup. Syntaxi jazyka C převzaly i jiné soudobé programovací jazyky jako na Java, Perl a PHP. Za nevýhodu jazyka C může být považován volný přístup do paměti, a tak špatně napsaný kód může způsobit přetečení zásobníku.
3.3
Chyby v programech
Syntaktické chyby Jedná se o chyby, které porušují pravidla definovaného jazyka. Vznikají z nepozornosti či roztržitosti programátora. Ve strukturovaném programování to často bývají překlepy, opomenutá interpunkční znaménka, nedefinované proměnné, či neukončené bloky zdrojového kódu. Tento typ chyby je kontrolován částí překladače nazývané syntaktický analyzátor, tudíž nelze pokračovat v překladu. Výstup chyby poskytuje chybová konzole rozhraní kompilátoru. Oznamování chyb se jednotlivými kompilátory liší. Cílem testování bude zejména hodnocení srozumitelnosti výstupu daného překladače pro programátora na nejrůznějších vzorcích a typech syntaktických chyb. (Pecinovský, 2008) Sémantické chyby Další časté chyby, které se u programování mohou vyskytnout, jsou chyby sémantické. Častou sémantickou chybou je vůbec nebo chybně nadeklarovaná proměnná. V případě práce s různými datovými typy, např. sčítání řetězce a čísla typu integer ohlásí překladač chybu nebo varování. (Vavrečková, 2008) Běhové a logické chyby Běhové chyby se vyskytují při běhu programu. Program se za určitých okolností dostane do nestandardního stavu a ohlásí chybu, případně se objeví výjimka. Běhové chyby se vyskytují zejména v jazycích s dynamickou typovou kontrolou. Nejčastěji se běhové chyby vyskytují v nedůsledné kontrole datových typů, kdy proměnná při běhu programu nabude neočekávané hodnoty a program dále nemůže pracovat. Tyto chyby se velmi špatně odhalují a často se objevují až při ostrém nasazení produktu do praxe. Principem logických chyb je jiná funkce výsledného programu, než byla původně programátorem zamýšlena. Logické chyby v kódu nemají vliv na samotný překlad – ten proběhne správně, ale program se chová výsledně jinak, než bylo očekáváno. Jako příklady logických chyb lze uvést nekonečný cyklus, špatně definovanou podmínku, zapomenutí volání určitého bloku kódu atd. Proti logickým chybám je třeba důkladného testování všech funkcí programu. (Pecinovský, 2008)
4
PŘEKLADAČE
4 4.1
19
Překladače Úvod do překladačů
Každý, kdo za svůj život napsal počítačový program v některém z vyšších programovacích jazyků, se musel setkat s pojmem překladač. Zdrojovému kódu v některém z programovacích jazyků samotný počítač nerozumí. Je tedy potřeba ho přeložit do takové podoby, aby mohl být spouštěn na běžném pracovním počítači. Překladač dokáže převést zdrojový kód ve vyšším programovacím jazyce do strojového kódu. Tudíž bychom ho mohli označit jako důležitý most mezi zdrojovým kódem, čitelným člověkem a posloupnosti instrukcí, čitelných procesory. Překladač je tedy počítačový program, který k libovolnému zdrojovému programu v nějakém jazyce vytvoří adekvátní počítačový program v cílovém jazyce. (Vavrečková, 2008) Základní rozdělení překladačů dle typu překladu: • kompilátory, • interprety. Základní rozdíl mezi kompilátorem a interpretem spočívá v tom, že u kompilace se zdrojový kód ve vyšším programovacím jazyku jednorázově převede na program, složený ze strojových instrukcí daného počítače. Program je nezávislý na svém zdroji a může být samostatně opakovaně spouštěn. Výstupem kompilace je binární soubor spustitelný na výsledném operačním systému (EXE, COM). U interpretu se zdrojový text nebude překládat do žádného jiného tvaru, a tudíž ani do takového tvaru, který by bylo možné spustit. Interpret postupně vykonává příkazy ve zdrojovém kódu vyššího programovacího jazyka a zajišťuje jejich provádění. Typickými zástupci interpretovaných jazyků jsou skriptovací jazyky PHP, Perl, Python a další. Každý způsob generovaní programů má své výhody a nevýhody. Výhodou interpretu je přenositelnost zdrojového kódu, malá závislost na platformě a také efektivnější vývoj. Velkou nevýhodou je provádění výsledného programu. Spuštění kompilovaného kódu je několikanásobně rychlejší, než provádění programu pomocí interpretu. (Peterka, 2011) V případě programování v jazyce C nebo Pascal po napsání zdrojového kódu se program přeloží a spustí se výsledný binární soubor. Pokud provedeme ve zdrojovém kódu nějaké změny, opět musíme spustit proces kompilace znovu. Pokaždé proběhnou všechny kroky překladu uvedené výše – lexikální analýza, syntaktická analýza, sémantická kontrola. V některých případech je přehlednější využít konverzační překladač. Toho se využívá pouze u jednoduchých jazyků. Princip konverzačního překladače spočívá v tom, že programátor postupně píše příkazy do zdrojového kódu a ty jsou ihned zpracovávány. Využití je zejména při výuce programování, kdy překladač okamžitě poskytne zpětnou vazbu – zejména hlášení o chybě, kdy ihned
20
4
PŘEKLADAČE
víme, kde vznikla. V praxi se konverzační interpret používá např. u programovacích jazyků Karel nebo Logo, které jsou určeny pro začátečníky v programování. (Vavrečková, 2008)
4.2
Princip práce překladače
Překladač se skládá z několika klíčových částí, které zajišťují jeho použití. Funkční principy překladače jsou níže rozebrány. Lexikální analýza Lexikální analýza spočívá v postupném čtení jednotlivých znaků vstupního zdrojového textu programu a vytváří z nich lexikální symboly programu (např. čísla, identifikátory, klíčová slova) a jednoznakové nebo víceznakové omezovače a oddělovače. Pro ukládaní identifikátorů a jmen návěští jsou používány tabulky symbolů. Lexikální analyzátor je tvořen deterministickým konečným automatem, který vznikl sjednocením, zřetězením a iterací automatů pro dané jazyky. Výstupy lexikální analýzy se nazývají tokeny, sekvence znaků zdrojového kódu se někdy označují jako lexémy. (Vavrečková, 2008) Syntaktická analýza Cílem syntaktické analýzy za použití výstupních symbolů lexikální analýzy je sestavení syntaktické struktury programu. Syntaktická analýza je vyjádřena derivačním stromem (Vavrečková 2008). Derivační strom je znázornění konstrukce věty pomocí pravidel bezkontextové gramatiky. Kořenem stromu je počáteční neboli startovací symbol gramatiky. Koncové listy stromů obsahují buď terminální symboly nebo prázdné slovo . Listy stromu, čtené zleva doprava, v jakékoliv fázi představují v zadané gramatice větnou formu. (Vavrečková 2008) Rozlišují se dvě metody syntaktické analýzy: • metoda zdola nahoru, • metoda shora dolů. U metody shora dolů začíná analýza kořenem derivačního stromu a postup procesu je směrem k listům při současné aplikaci a výběru vybraných pravidel gramatiky. Pří aplikaci metody zdola nahoru se postupuje od listů směrem ke startovacímu symbolu. U nedeterministických gramatik je potřeba aplikovat syntaktickou analýzu s návraty. (Rybička, 2005) V případě neúspěchu syntaktické analýzy ohlásí překladač syntaktickou chybu (syntax error) a překlad není úspěšně dokončen.
4.2
Princip práce překladače
21
Sémantická analýza Další a neméně důležitou částí překladače je sémantická kontrola, která je implementována jako sémantický analyzátor. Jak již napovídá význam slova sémantika, tak účelem sémantické analýzy je přiřadit význam jednotlivým symbolům. Sémantický analyzátor postupně prochází symboly, které poskytne syntaktická analýza a přiřazuje jim významy. Zároveň zjišťuje, zda daný objekt byl deklarován nebo již použit. Objekty jsou míněny funkce, procedury, proměnné atd. V praxi to znamená, že překladač kontroluje práci programu s datovými typy. Pokud se programátor pokusí sečíst dva různé datové typy – např. datový typ integer a datový typ řetězec, překladač prostřednictvím sémantického analyzátoru vypíše u některých programovacích jazyků chybové hlášení. Výstupem sémantické analýzy je intermediární kód, který je dále zpracováván. Je obvykle přeložen do cílového kódu. Intermediární kód může být ve více variantách. Jedna z variant je tříadresový kód, který má dobrou podporu optimalizace, a tak se častěji využívá v kompilačních překladačích. Naopak grafová reprezentace je výhodnější pro interpretační překladač, protože výrazy jsou ve formě sémantického stromu, který lze vyhodnocovat průchodem postorder. Mezikód, který je vhodný jak pro překladač tak pro interpret, se označuje jako zásobníkový kód. Zásobníkový kód je založen na postfixu, kde se operátory nacházejí až za operandy. Výhodou je také absence závorek. (Vavrečková, 2008)
Obr. 1: Schéma kompilačního překladače
22
4
PŘEKLADAČE
Průchody překladače Před objasněním principu průchodů překladače je nezbytné popsat, jakým způsobem mohou být překladače konstruovány. Překladač lze navrhnout několika způsoby, většina překladačů bývá rozdělena na dvě části. Část závislá na vstupním jazyce se nazývá front-end a druhá část, která závisí na cílové architektuře, se označuje jako back-end. Překlad nemusí probíhat přímo, může využívat tzv. mezikód (bytekód), tzn. že kód je nejprve překládán do mezikódu a poté je teprve převeden do strojového jazyka. Kód slouží pak jako mezistav, který pak může být převeden na více architektur. Překladače lze dál rozdělit na dvě skupiny dle počtů průchodů: • jednoprůchodové, • víceprůchodové. Jak bylo vysvětleno v předchozí kapitole, překlad probíhá postupně za pomocí lexikální, syntaktické a sémantické analýzy. Lze ale rozlišit, zda všechny tyto kroky proběhnou v jedné fázi, nebo zda se rozdělí do více průchodů překladu. Nemusí platit, že jeden průchod bude odpovídat například lexikální analýze a druhý průchod syntaktické analýze. Jednoprůchodové překladače se vyznačují tím, že všechny součástí překladače se spustí postupně během jednoho průchodu překladu. Výhodou tohoto řešení je absence mezikódu, který by se musel uchovávat v paměti, a pak s ním dále do budoucna počítat. Jednoprůchodový překlad je vhodný pro jednoduché jazyky, které není třeba příliš důkladně optimalizovat. Víceprůchodový překladač naproti tomu musí uchovávat vytvořený mezikód pro další průchody překladu. Výhodou víceprůchodových překladačů je to, že při překladu zabírá místo v paměti pouze některá část překladače – např. lexikální analýza. Víceprůchodové překladače vylepšují možnosti optimalizace zejména složitých a rozsáhlých algoritmů. (Vavrečková, 2008)
4.3
Jazyk symbolických adres
V nedávné minulosti neexistovaly programovací jazyky, jak je známe dnes. Vzhledem k faktu, že tvořit programy v číselných kódech bylo značně neefektivní a náročné, začal se od padesátých let minulého století používat jazyk symbolických adres (JSA). Jazyk symbolických instrukcí je nízkoúrovňový programovací jazyk, který je založen na strojových instrukcích. Programy, napsané v JSA, jsou svázané s daným procesorem, a tak jsou obtížně přenositelné na jiné platformy. Překladač, který jazyk symbolických instrukcí převede do strojového kódu, se nazývá Assembler. Jazyky symbolických instrukcí se používaly do devadesátých let minulého století, kdy je vytlačily vyšší programovací jazyky (C, Basic, Pascal atd.), které do programování přinesly více abstrakce a zjednodušení tvorby algoritmů. K nejznámějším překladačům JSA patří např. Flat Assembler nebo Netwide Assembler.
4.4
23
Integrovaná vývojová prostředí
Skladba programu v JSA: • překladové direktivy, • metoda shora dolů, • strojové instrukce, • definice obsahu paměti, • makra, návěští, • podmínkové bloky, • definice překladových symbolů. Program, který naopak převádí strojový kód zpět do jazyka symbolických adres, se nazývá disassembler. Dokáže přeložit binární podobu programu do částečně čitelného kódu. Tato funkce se používá zejména tehdy, není-li přístup k původním zdrojovým kódům a je potřeba proniknout do principu práce programu. Tato technika bývá využita počítačovými crackery např. pro prolomení různých softwarových ochran. Typickým příkladem je vytvoření neoficiálního patche pro zkušební verzi softwaru zjištěním daných podmínek. Disassemblery ale také využívají výrobci antivirů, kteří tuto techniku uplatňují pro zkoumání počítačových virů. K volně šiřitelným disassemblerům patří Netwide Disasssembler. Následuje ukázka kódu získaného z disassembleru programem Netwide Disassembler ze vzorku jednoduchého programu jazyka C. ... 00001BDA 00001BDF 00001BE1 00001BE2 00001BE9 00001BEA 00001BEB 00001BEC 00001BEE 00001BF1 00001BF2 ...
4.4
696E005F4A 765F 52 65676973746572 43 6C 61 7373 657300 5F 696E697400
imul bp,[bp+0x0],word 0x4a5f jna 0x1c40 push dx imul si,[gs:ebx+0x74],word 0x7265 inc bx insb popaw jnc 0x1c61 gs jnc 0x1bf1 pop di imul bp,[bp+0x69],word 0x74
Integrovaná vývojová prostředí
V soudobých programovacích jazycích jsou samotné překladače součástí integrovaných vývojových prostředí (IDE). Integrované vývojové prostředí je programový balík sestávající z několika částí. Zahrnuje obvykle editor zdrojového kódu, překladač, linker a debugger. O principu překladačů a jejich struktuře již bylo zmiňováno v předchozích částech práce. Editor zdrojového kódu se skládá z pokročilejšího textového editoru, uzpůsobeného pro tvorbu zdrojových kódů. Samozřejmostí bývá
24
4
PŘEKLADAČE
zvýrazňování syntaxe, popřípadě automatické doplňování znaků. V neposlední řadě bývá součástí IDE prostředí také vizuální programování, které umožní poskládat logické prvky programu a poté následně prostředí vygeneruje zdrojový kód pro překlad programu. Programátor se tak nemusí zdržovat rutinními operacemi. V práci jsou zkoumána prostředí jazyka Pascal a C. (Integrovaná vývojová prostředí, 2012) Typy vývojových prostředí: • typové, • universální. Typová vývojová prostředí jsou vázána na konkrétní jazyk a tvoří jeden celek. Příkladem může být Free Pascal IDE, Pelles C IDE atd. Naproti tomu universální vývojová prostředí mohou pracovat s více programovacími jazyky. Typickými zástupci jsou prostředí Netbeans a Eclipse, která pracují pod více operačními systémy.
Obr. 2: IDE Pelles C
Linker Pro řadu programátorů je funkce linkeru velkou neznámou. Běžný vývojář po napsání zdrojového kódu vybere možnost překladu a ve výstupu se mu objeví až výsledný spustitelný soubor v binární podobě. Tak jednoduché to ale není. Po překladu zdrojového kódu se vytvoří výsledný binární soubor, který ovšem sám o sobě není na dané platformě spustitelný. Jedná se o tzv. mezikód, někdy také označovaný jako object code. Nyní přichází na řadu linker, který převede tento mezikód do spustitelné podoby. Nejdůležitější úlohou linkerů je spojování mezikódů do jednoho spustitelného souboru – linkování. Tímto způsobem mohou být sdíleny jednotlivé části kódu
4.4
Integrovaná vývojová prostředí
25
mezi moduly. Linker se tedy stará o umisťování objektů v adresním prostoru daného programu za použití relokačního kódu a obsluhuje vyhledávání symbolů v ostatních objektových modulech. Relokační strojový kód obsahuje přesměrování absolutních skoků, načtení a uložení. U dnešních operačních systému se uplatňuje především dynamické linkování, které adresaci nespecifikovaných symbolů provede až při spuštění binárního programu, kde se teprve provede finální sestavení programu. Vzhledem ke skutečnosti, že dnes lze již překládat velmi velké zdrojové kódy většiny jazyků, slouží linker především pro připojování knihoven k hlavnímu programu. (Peterka, 2011) Většina překladačů má možnost volby, zda má být spuštěna pouze kompilace nebo kompilace včetně samotného linkování. Součástí integrovaných prostředí je i samostatné linkování objektových modulů do výsledné spustitelné binární podoby. Debugger Při programování se určitě každému z nás stalo, že udělal v kódu nějakou chybu. Jak již vypovídá sám název, debugger má za cíl poskytnout vývojáři srozumitelný chybový výstup, který mu ulehčí vývoj programu. Chybová hlášení, se kterými se nesporně setkal již každý programátor, jsou nedílnou součástí každého ladění. O tyto funkce se stará právě již zmiňovaný debugger. Většina vývojových prostředí má integrovaný debugger, který tyto funkce vykonává. Existují ale také externí debuggery, často výkonnější než ty integrované. Jako příklad open-sourcového debuggeru lze uvést GNU Debugger, který podporuje i vzdálené debuggování. Utilita Make Překladač provádí samotnou kompilaci, optimalizaci a ladění zdrojových kódů. Pokud jsou ale překládány velké projekty, ruční překlad zdrojových programů je značně neefektivní. Pro kompilaci větších celků se hojně využívá program Make, který je dostupný prakticky na všech unixových platformách. Utilita Make potřebuje ke svému běh soubor Makefile, kde jsou popsány závislosti souborů na jiných souborech nebo knihovnách. Makefile tedy snadno dokáže řešit vazby programů na další zdrojové nebo hlavičkové soubory. Makefile je obyčejný textový soubor. Příklad struktury Makefile: # program: main.o net.o gui.o $(CC) -o $@ main.o net.o gui.o main.o: main.c net.h gui.h net.o: net.c net.h gui.o: gui.c gui.h
26
4
PŘEKLADAČE
Pro vlastní projekty je možné si takový soubor vyrobit dle specifikace. Pro kompilaci větších projektů se používá automatického skriptu ./configure, který prozkoumá daný operační systém z hlediska umístění knihoven a vygeneruje soubor Makefile pro konkrétní softwarovou platformu. Teprve poté se spouští překladová utilita Make, která provede kompilaci a linkování. Utilita Make se používá zejména v Linuxových operačních systémech, kde kompilace je často jedinou možností instalace softwaru. Ve vývojových prostředích se využívá pro kompilaci projektů, kde se spouští zcela automaticky po přeložení softwarového projektu. Optimalizace Optimalizace programu je proces přeuspořádání a změny operací pomocí překladače tak, aby bylo možno dosáhnout efektivnějšího cílového programu. Optimalizační metody lze rozdělit do dvou kategorií. První kategorií jsou metody, které se používají při transformování zdrojového programu a nezávisí na cílovém jazyku. Do druhé kategorie logicky pak patří metody, které jsou jistým způsobem závisle ná použitém programovacím jazyku. Překladačů se bezesporu týká první zmíněná kategorie. (Gries, 1981) Čtyři základní metody optimalizace: • předvýpočet, • odstraňování přebytečných informací, • přesouvání operací mimo cyklus, • redukce síly násobení v cyklech. U předvýpočtu se už během kompilace vykonají operace programu, které už jsou v daném čase známé, a tak se ušetří čas v průběhu samotného programu. Metoda předvýpočtu se používá nejčastěji pro aritmetické operátory. Odstraňování přebytečných informací je další používanou metodou optimalizace. Operace se v daném bloku považuje za nadbytečnou, pokud před ní existuje stejná operace a žádná proměnná, na které závisí tato operace, se nemění jinou operací, které by to mohla ovlivnit. Tato operace je pak považována za redundantní a v rámci optimalizace dojde k její eliminaci. Obdobně funguje také optimalizace cyklů, kde se invariantní operace přesouvají mimo cyklus. (Gries, 1981) Řada současných překladačů má možnost nastavení konkrétní optimalizace – nejčastěji to bývá optimalizace k velikosti výsledného souboru, popřípadě času kompilace. Velké optimalizační možnosti v tomto směru má překladač GCC jazyka C.
4.4
Integrovaná vývojová prostředí
27
Preprocesor Preprocesor lze definovat jako speciální program používaný v jazycích C a C++ pro zpracovávání maker a symbolických konstant. Preprocesor provádí pouze textové náhrady definovaných symbolů v textu a umožňuje podmíněný překlad. Preprocesorové příkazy začínají znakem mřížky (#) – #define nebo #ifndef. Preprocesor je součástí překladu zdrojového kódu. (Němec, 2005) Základní rozdělení preprocesorů: • lexikální preprocesor, • syntaktický preprocesor, • universální preprocesor. Lexikální preprocesor je nejnižší stupeň preprocesoru. Ke své práci využívá pouze lexikální analýzu. Syntaktické preprocesory jsou sofistikovanější programy a používají se pro přizpůsobení jazyka. Univerzální preprocesory naopak nejsou svázány s jedním kompilátorem a jazykem. Nejpoužívanějším preprocesorem je preprocesor jazyka C, který se používá pro připojování hlavičkových souborů a tvorbu maker. Preprocesor přijde na řadu ještě před vlastním překladem a linkováním a provádí úpravy na úrovni textu. Může vypouštět komentáře, nahrazovat symboly nebo vkládat soubory. Preprocesor také usnadňuje podmíněný překlad a jsou díky němu výsledné programy přenositelnější. Na druhou stranu ovšem i překlad malého programu po načtení potřebných knihoven je relativně dlouhý, protože includování standardní knihovny přinese několik stránek vygenerovaného kódu navíc. (Němec, 2005) Ukázka využití preprocesoru pro podmíněný překlad: #define LADENI /* nějaký kód */ #ifdef LADENI printf("Proměnná je ..."); #endif JIT Překladače JIT (Just-in-time) patří ke speciálním metodám překladu, které využívají různé techniky pro zrychlení běhů programů, které jsou přeložené do mezikódu. Program je v době překladu převáděn rovnou do nativního strojového kódu. To má výhodu pro spouštění programů na různých platformách, kde pak výsledný program dokáže běžet několikanásobně rychleji, než kdyby byl již předkompilován. Výsledný program pak může využít i rozšířené instrukce použitého procesoru. (Peterka, 2009)
28
4
PŘEKLADAČE
Nevýhodou JIT může být pak delší spuštění programu, protože se musí provést na počátku spuštění překlad. Čím více je daný kód optimalizován, tím lepší a efektivnější kód je možné získat, ale také pak delší dobu trvá počáteční spuštění. Z toho důvodu se rozšířily optimalizátory JIT překladů, které kombinují kompilační a interpretační překlad pro rychlejší spouštění. (Peterka, 2009) Používané metody JIT: • vkládání těl metod, • odstranění mrtvého kódu, • rozbalování smyček. Princip JIT překladu nachází uplatnění zejména u objektového programovacího jazyka Java, kde je hojně využíván. Refaktoring Mnoho programátorů po napsání zdrojového kódu programu nebo většího projektu kontroluje zdrojový kód a zjednodušují a zefektivňují zdrojový kód, například odstraňováním duplicit. Pokud se ale jedná o velký projekt, „čištěnímÿ by vývojář trávil nekonečné hodiny. Na řadu tedy přichází automatizovaný refaktoring. (Fowler, 2003) Refaktoring je v programování poměrně nová věc. Své využití má zejména v objektových programovacích jazycích. Principem refaktoringu jsou změny v softwarovém produktu, které nemají vliv na chování kódu, ale zlepšují jeho strukturu, efektivitu a strukturu. Refaktoring tedy probíhá až poté, co je zdrojový kód napsán. Probíhá ve velké míře automaticky, a tak rizika vzniku chyb jsou velmi malá. Pro uvedení do problematiky refaktoringu je zde uveden přehled nejčastějších situacích, kdy refaktorovat: (Fowler, 2003) • • • •
duplicitní kód, dlouhá metoda, velká třída, dlouhý seznam parametrů.
Řadu postupů a technik refaktoringu lze definovat a algoritmizovat, takže se refaktoring může provádět automaticky. Podporu refaktoringu nabízí některá již zmiňovaná vývojová prostředí – např. Eclipse.
4.5
Vybrané překladače a vývojová prostředí jazyka Pascal
V následujících odstavcích jsou vyjmenovány a krátce popsány testované a hodnocené překladače. Informace byly čerpány převážně z oficiálních webových stránek překladačů a z jejich dokumentace. Za každým překladačem je odkaz na oficiální nebo komunitní stránky každého z nich.
4.5
Vybrané překladače a vývojová prostředí jazyka Pascal
29
Free Pascal (http://www.freepascal.org/iri) Free Pascal je jeden z nejznámějších open-source překladačů programovacího jazyka Pascal a Object Pascal, který se stále vyvíjí. Na oficiální webových stránkách projektu lze překladač stáhnout pro různé platformy a operační systémy. Tvůrci Free Pascalu se snaží o maximální kompatibilitu s jazykovými implementacemi Turbo Pascal a také s Delphi od společnosti Borland. Je kompatibilní s prvky jazyka Delphi. Irie Pascal (http://www.irietools.com/index.html) Irie Pascal patří k těm méně známým překladačům programovacího jazyka Pascal, které zahrnují plnou implementaci jazyka Pascal – konkrétně Standard Pascal (ISO/IEC 7185). Jedná se o komerční překladač, který poskytuje společnost Irie Tools. Na oficiálních webových stránkách je k dispozici zkušební verze. Omezení spočívá ve velikosti generovaného programu a generovaný program po jednom dni přestane pracovat. Výsledný program může být generován buď klasicky do strojového kódu – v případě Windows do souboru s příponou EXE nebo do tzv. bytekódu souborů s příponou ivm. Zajímavou funkcí je podpora serverových aplikací generováním výsledných cgi skriptů. Irie Pascal patří k multiplatformním překladačům. Překladač včetně IDE je dostupný pro operační systémy Windows, OS Linux (Red Hat), Solaris, Free BSD. Virtual Pascal (http://www.vpascal.com/) Virtual Pascal je další z řady volně dostupných kompilátorů Pascalu. Byl navržen Vitaly Miryanovem a je určen primárně pro operační systém Windows. Byla doplněna podpora také pro MS-DOS, OS/2 nebo Linux. Prostředí Virtual Pascalu disponuje kromě kompilátorů také vývojovým prostředím. Vývoj byl ukončen v roce 2005. Na svém webu autoři uvádí, že vytváří velmi malé spustitelné soubory nebo také disponuje možností editace kódu při překladu. Vývoj Virtual Pascalu byl již ukončen v roce 2005. Turbo Pascal (http://pascal.webz.cz/index.php?part=down) Turbo Pascal je jednou z nejznámějších implementací Pascalu od společnosti Borland, často používanou ve výuce. Obsahuje komplexní vývojové prostředí určeno pro MS-DOS – samotný kompilátor, debugger, textový editor a linker. Turbo Pascal pracuje ještě v 16bitovém subsystému. Od verze 5.5 podporuje Turbo Pascal i objektové programování, i když jinak patří ke strukturovaným programovacím jazykům. Nástupcem Turbo Pascalu se stalo vývojové prostředí Delphi pro MS Windows, které je založeno na objektech v jazyce Pascal.
30
4.6
4
PŘEKLADAČE
Vybrané překladače a vývojová prostředí jazyka C
GCC (http://gcc.gnu.org/) Zkratka GCC pochází ze slova GNU compiler collection a definuje sadu překladačů, která je schopna zpracovávat jazyky C, Ada, C++, Objective-C, Fortran a Java. Jedná se o nejpoužívanější a nejznámější překladač jazyka C. Je multiplatformní, a tak ho lze spustit systémech na bázi UNIX i v MS Windows. GCC překladač je součástí každé linuxové distribuce již v základní instalaci. Tiny CC (http://bellard.org/tcc/) Tiny C compiler je multiplatofrmní překladač jazyka C, původně určený pro unixové systémy. Od verze 0.9.23 je dostupný i na platformě OS Windows. Podporuje standardy ANSI-C i ISO a na stránkách dokumentace autoři uvádějí, že předností tohoto kompilátoru jsou velmi malé binární soubory i rychlá doba překladu. V následujících testech bude toto tvrzení ověřeno. Tiny C compiler bylo možné instalovat z repozitářů použité linuxové distribuce. Clang (http://clang.llvm.org/) Překladač Clang je dalším používaným kompilátorem jazyka C. Jako backend využívá infrastrukturu LLVM (Low Level Virtual Machine). Překladač je určen primárně pro systémy OS UNIX a je součástí repozitářů distribucí. V experimentální verzi je však dostupný i pro platformy OS Windows. Nwcc (http://nwcc.sourceforge.net/lcc) Nwcc je menší projekt linuxového kompilátoru, který napsal ve volném čase Nils Weller. Překladač je vyvíjen od roku 2003 a stále vychází nové verze. Dle informací na webových stránkách může směle konkurovat zavedeným kompilátorům. Kód je vytvořen v jazyku C a je napsán na osmdesát tisíc řádků včetně backendu. Lcc-win (http://www.cs.virginia.edu/~lcc-win32/) Lcc je kompilátor, který podporuje pouz ANSI-C. Lcc kompilátor je popsán v knize A Retargetable C Compiler: Design and Implementation (Addison-Wesley). Lcc je distribuován ve verzi pro Windows a Linux. Port pro OS Windows se jmenuje Lccwin a autorem je Jacob Navia. Kompilátor Lcc je k dispozici jak pro 64bitovou verzi, tak pro 32bitovou verzi operačního systému. Kompilovat programy lze přes příkazovou řádku nebo skrz IDE rozhraní. Lcc-win je šířen zdarma pro nekomerční využití. Další informace lze nalézt na oficiálním webu.
4.7
Časová a prostorová složitost
31
Pelles C (http://www.pellesc.de/) Pelles C je další kompilátor jazyka C pro operační systém rodiny Windows. Zakladatelem je uváděn autor označován jako Pelle, který stál u zrodu projektu. Pelles C je open source a zahrnuje IDE prostředí. Tvůrce se inspiroval u autorů překladače Lcc, na kterém je založen. Kromě klasických konzolových a okenních aplikací umožňuje vyvíjet programy i pro Pocket PC (Windows Mobile).
4.7
Časová a prostorová složitost
Problematiku časové a prostorové složitosti lze zařadit do oboru teorie složitosti. Zde se systematicky zkoumá cena výpočtu měřená v časových jednotkách, nebo prováděných operacích. Kritériem může být také spotřebované množství paměti. Cílem je podniknout takové měření, aby srovnání srovnání algoritmů bylo objektivní. Předmětem zkoumání je v informatice často složitost algoritmu. Způsoby vyšetřování složitosti algoritmů: • exaktně, • neformálně. Exaktní analýza je prováděna pomocí nástrojů matematického aparátu. Naproti tomu neformální analýza je prováděna bez speciálních matematických aparátů a používá se především ke srovnání složitostí několika algoritmů. Problémem této neformální analýzy je doba trvání dílčích operací, která není přesně určena. (Kreslíková, 2004) Přehled typických složitostí algoritmů: • konstantní, • logaritmická, • lineární, • kvadratická, • kubická, • exponenciální. Pro účely měření časové a prostorové náročnosti daného překladače je však potřeba změřit časovou a paměťovou náročnost vykonání jisté části programu, produkované z různých překladačů. V práci je zkoumána časová a paměťová náročnost překladačů na vybraném testovacím hardwaru a softwaru. K tomuto účelu jsou popsány a použity nástroje, které jsou zmiňovány v praktické části diplomové práce.
32
5
5
TESTOVÁNÍ VLASTNOSTÍ PŘEKLADAČŮ
Testování vlastností překladačů
Testování softwaru je nedílnou součástí tvorby softwaru a patří mezí základní metody softwarového inženýrství. Zejména při vývoji rozsáhlého softwaru je důkladné testování nezbytné. Lze rozlišovat dvě základní metody testování softwaru: • validace, • verifikace. Verifikací označujeme proces testování hledající odpověď na otázku, jestli je softwarový produkt vytvářen správně. Jinými slovy lze říci, že se hledají nedostatky v samotném softwarovém systému. Jedná se tedy o hledání softwarových chyb. (Vondrák, 2002) Po verifikaci přichází na řadu validace. Validace je proces testování, který zkoumá, zdali vytvářený software je správný. Pomocí validace softwaru se zjišťuje, zda softwarový systém odpovídá požadované funkcionalitě. Verifikace a validace tvoří při testování spojené nádoby. Může se tedy stát, že softwarový produkt vyhoví procesu verifikace, ale neobsahuje požadovanou funkcionalitu. Na druhou stranu může zadanou funkcionalitu splňovat, ale bude obsahovat velké množství chyb. Kromě verifikace a validace se používají metody ověřování, které mohou být statické nebo dynamické. Statické techniky se zabývající testováním modelů a diagramů a umožňují ověřovat korespondenci mezi vytvořeným systémem a jeho specifikací. Dynamickými technikami rozumíme ověřování již hotového softwaru z hlediska jeho vstupů a výstupů. (Vondrák, 2002) Modely testování: • testovací procedury, • testovací úlohy, • testovací komponenty. Testovací úlohy definují, co se má na systému testovat. Jakým způsobem a jakými metodami – to určují testovací procedury. Pro pokročilejší testování se využívají testovací komponenty, které zautomatizují použití testovacích procedur. Výše uvedené modely testování se dají využít dvěma způsoby přístupu k testování softwaru. Prvním způsobem chápání softwaru jako celku a přístupu ke zdrojovým kódů a procesu vývoje je white-box testování. Druhý způsob, kdy se tester zaměřuje pouze na vstupy a výstupy daného produktu, se nazývá black-box testování. V diplomové práci bude kladen důraz zejména na druhý způsob testování, zejména také z důvodu, že hlavní funkcí překladačů je na základě nějakého vstupu poskytnout co nejlepší a nejefektivnější výstup.
5
33
TESTOVÁNÍ VLASTNOSTÍ PŘEKLADAČŮ
Jakým způsobem testovat a hodnotit vlastnosti překladače? Vzhledem k tomu, že se jedná o hotové produkty, které srovnáváme, nemůžeme tedy testovat a hodnotit jejich vývoj. Předmětem testování a hodnocení budou především výstupy na základě vytvořených vstupů, které danému překladači předložíme ke zpracování. V případě překladačů to jsou zdrojové kódy programovacího jazyka, se kterými překladač pracuje. Průzkum zdrojových kódů a efektivita algoritmu, ve kterých jsou dané překladače napsány, by byl jistě také zajímavý, ale zpracování těchto informací by bylo nad rámec této diplomové práce. Pro programátora, který si vybírá překladač, popřípadě integrované vývojové prostředí k překladu svých produktů, jsou důležitá kritéria jako uživatelská přívětivost IDE prostředí, srozumitelnost výstupu překladače, paměťová náročnost výsledného programu, platforma, rychlost zpracování zdrojového kódu, podpora specifikace a standardů daného jazyka nebo také dostupnost dokumentace a nápovědy. Literatury, zabývající se testováním schopností překladačů nebo vývojové prostředí, je relativně málo. Existují softwarové nástroje, které hodnotí, zda daný překladač odpovídá dané specifikaci jazyka. Na webu http://www.plumhall.com si lze stáhnout nástroj, který otestuje překladače v jazycích C, C++, Java a C#. Nástroj testuje specifikaci ANSI C a ANSi C++. Jedná se však o komerční produkt. V této práci však tento nástroj pozbývá smysl, protože u testovaných překladačů předpokládáme, že vyhovují dané specifikaci, jež mají uvedenou v dokumentaci. Pro jazyk C je k dispozici několik studií, které se zabývají výkonem překladačů. Zajímavým příspěvkem na webu http://www.simulanalog.org je od Thomase Serafiniho testování rychlosti vybraných instrukcí, které byly přeloženy různými kompilátory za použití funkce clock(), která určí čas provádění daných instrukcí. Čím kratší čas, tím efektivnější je daný strojový kód. V tabulce 1 je čas udáván ve vteřinách. Tab. 1: Testování rychlosti (Serafini, 2002) Visual C++ Intel GCC 4.5.2 CW 5.0 PC 6.0 Compiler 5.0 Float matrix multiplication
1,48
1,54
1,62
1,45
Integer conditional move
0,83
0,61
1,97
1,48
Float conditional move
1,15
0,89
2,16
1,84
Lookup table accessing
1,54
1,29
2,12
1,33
Float biquad filter
3,02
3,98
3,62
2,71
Computing biquad coefficents
1,26
1,76
1,39
1,95
Int biquad filter
2,20
2,57
2,81
2,41
34
5
TESTOVÁNÍ VLASTNOSTÍ PŘEKLADAČŮ
Dalšími analýzami v testování překladačů se zaměřením na čas kompilace a velikost výsledného spustitelného souboru se zabývá web Willus.com. Zaměřuje na několik kompilátorů, které testuje na vybraných vzorcích a různých procesorových architekturách. Zkoumá i rozdíly výkonu mezi jednotlivými parametry překladače. Testovány jsou strukturované jazyky Fortran a C. Testované soubory jsou velmi rozsáhlé, a tak jsou velikosti binárek a časy kompilace relativně vysoké. U jazyka Pascal nebyly nalezeny žádné zdroje, které by se zabývaly srovnáním parametrů překladačů. Řada kompilátorů jazyka Pascal se již dnes nepoužívá a není dostupná, ať už z důvodu, že šlo o projekt, který časem zastaral a přestal být podporován, nebo z důvodu přechodu vývojářů na jiné programovací jazyky. Nicméně jazyk Pascal je stále používaný – zejména k výuce programování kvůli relativně snadné syntaxi. Z jazyka Pascal byla vybrána čtyři dosud používaná vývojová prostředí Free Pascal, Virtual Pascal, Turbo Pascal a Irie Pascal. Překladače jazyka Pascal byly testovány na platformě Windows. Z vývojových prostředí a překladačů jazyka C byly testovány GCC, Tiny CC, Clang a Nwcc kompiler. Vzhledem k tomu, že jsou dané překladače určeny primárně pro OS UNIX, byly testovány a hodnoceny na linuxové platformě. Pod OS Windows byly testovány překladače Lcc-win a Pelles C. Hodnocené překladače a jejich vývojová prostředí včetně verzí: • Jazyk Pascal: – Free Pascal 2.4.4 – Irie Pascal 2.6 – Turbo Pascal 7.0 – Virtual Pascal 2.1 • Jazyk C: – Clang 2.8 – GCC 4.5.2 – Lcc-win 32-bit – Nwcc 0.8.2 – Pelles C 6.50 – Tiny CC 0.9.25 Některé překladače disponují integrovaným vývojovým prostředí, pro ostatní je možné využít některé z alternativních prostředí. Níže uvedená tabulka představuje přehled překladačů a dostupných vývojových prostředí a podporovaných platforem daných překladačů. Zkoumány byly platformy MS Windows, UNIX a Mac OS. Pokud je u překladače uvedena položka Multiplatformní, je překladač dostupný pod všemi zkoumanými systémy.
5.1
35
Testovací vzorky
Tab. 2: Vybraný přehled překladačů
5.1
Vývojové prostředí (IDE)
Platforma
Free Pascal
ANO
Multiplatformní
Irie Pascal
ANO
Multiplatformní
Turbo Pascal
ANO
Windows
Virtual Pascal
ANO
Windows
GCC
NE
Multiplatformní
Clang
NE
Multiplatformní
Tiny CC
NE
UNIX, Windows
Nwcc
NE
UNIX, Mac
Lcc-win
ANO
Windows
Pelles C
ANO
Windows
Testovací vzorky
Testovací vzorky jsou nedílnou součástí a zároveň důležitou pomůckou pro zkoumání schopností a vlastností překladačů. Testovací vzorky představují zdrojové kódy v jazyce C a Pascal, které obsahují algoritmy, zkoumající vždy danou vlastnost a oblast překladače. V práci se využívají upravené testovací vzorky z databáze vzorků pro jazyk Pascal, které jsou dostupné na webu http://www.cs.vassar.edu/˜cs331/. Tyto vzorky jsou použitelné jen pro některé části hodnotících kritérií, pro další oblasti bylo nutné vzorky navrhnout a vhodně uzpůsobit pro daný test. Pro jazyk C byly navrženy vlastní vzorky. Pro reakce překladače na syntaktické a sémantické chyby jsou navrženy vzorky pro jednotlivé typy těchto analýz. Vzorky obsahují vždy typickou situaci pro danou chybu. Například lze jmenovat chybějící středník, neinicializovaná proměnná, chybně definované pole atd. Výsledky jsou pak logicky členěny dle typu daných chyb. Pro testovaní časových a paměťových náročností jsou pak použity takové vzorky, jejichž výstupy jsou dobře měřitelné vybranými nástroji a výsledky lze pak jasně interpretovat.
5.2
Hodnotící a porovnávací kritéria
Hodnocení vlastností překladačů vybraných překladačů strukturovaných jazyků tvoří klíčovou náplň diplomové práce. Záměrem práce není výslovné testování softwaru, zda splňuje bezchybnou funkcionalitu definovanou v popisu a v dokumentaci, nýbrž vzájemné porovnání jednotlivých vlastností na základě definovaných kritérií. Ke každému programovacímu jazyku existuje více překladačů zdrojového kódu a každý disponuje jinými vlastnostmi. Vzájemné porovnání schopností překladačů programovacích jazyků vyžaduje pečlivé zvážení a stanovení hodnotících kritérií. Na webu existuje řada odborných srovnání, která porovnávají vždy pouze vybranou
36
5
TESTOVÁNÍ VLASTNOSTÍ PŘEKLADAČŮ
vlastnost několika překladačů (rychlost, velikost výsledných souborů atd.). Většina těchto testů se zabývá dílčím srovnáním – např. benchmarky několika málo překladačů. Komplexní porovnání důležitých vlastností daných překladačů však žádná obdobná práce nesrovnává. Definovaná kritéria: • Časová a prostorová složitost překladače: – paměťová náročnost, – doba kompilace, – efektivita strojového kódu. • Reakce překladačů na chyby: – syntaktické chyby, – sémantické chyby, – logické chyby, – běhové chyby. • Dokumentace • Specifika daného jazyka V další části práce jsou jednotlivá kritéria rozebrána a podrobněji definována. Testovací procedury a jejich parametry jsou obsáhle popsány a přehledně interpretovány dle jednotlivých kritérií. Pro přehlednost a názornost jsou významné výsledky uspořádány do tabulek, které umožňují snazší srovnání daných parametrů.
5.3
Využité nástroje a testovací prostředí
Pro testování překladačů byl použit Notebook Acer Extensa 5635Z s operační pamětí 3 GB RAM a procesorem Intel 2.1 GHz. Jako zástupci operačních systému byly vybrány 32bitové operační systémy Windows 7 a Linux Mint 11 Katia s verzí jádra 2.6.38-8. Pro testování časové náročnosti překladačů byl využit v OS Linux integrovaný program time, který dokáže změřit hodnoty běhu vykonání daného příkazu. V operačním systému taková utilita není součástí systému. V OS Windows byla použita utilita timeit, které je součástí balíku Windows Server 2003 Resource Kit Tools. V obou případech postačuje pro zjištění časové náročnosti kompilace postačuje před spuštěním samotné kompilace přidat příkaz time nebo timeit. Některá vývojová prostředí obsahují mají v sobě již zabudovaná měření času, kdy nám hodnoty poskytne samotné rozhraní programu nebo vývojové prostředí. Pro paměťovou náročnost programů (RAM) bylo využito standardních nástrojů v obou systémech. Ve Windows 7 dostatečný přehled poskytuje správce procesů, v OS Linux se jedná o programy top a htop.
5.4
5.4
Syntaktické a sémantické chyby
37
Syntaktické a sémantické chyby
Jazyk Pascal S ohledem na využití programovacího jazyka Pascal pro výukové účely a jeho použitím v akademické sféře jako prostředku zápisu algoritmu je důležitým kritériem také uživatelská přívětivost každého daného překladače. Pro tyto účely byly použity vzorky z databáze vzorků a vlastní vzorky. Na jednoduchém vzorku, který testuje výrazy, lze otestovat chování překladačů na řadu syntaktických a sémantických chyb. Je nepochybné, že u finálních produktů není třeba testovat, zda překladače reagují na vybrané chyby. Cílem této kapitoly je zmapovat reakce jednotlivých překladačů a vyhodnotit nejlepší kompilátor z každého jazyka. Ke kvalitě a schopností překladačů se zde přidávají i vývojová prostředí, která integrují mnohá vylepšení – zejména vizuální upozornění na nejrůznější syntaktické chyby. Z čtyřech testovaných překladačů má nejpokročileji zpracované zobrazování chyb vývojové prostředí Virtual Pascalu. Kromě upozornění na chybu, zobrazí v ladícím okně i kus zdrojového kódu, ve kterém je příslušná chyba nalezena. Na konci kapitoly je přehledně zobrazena tabulka s jednotlivými chybovými výpisy pro různé typy chyb syntaktické a sémantické analýzy. Překladače byly testovány ve stavu standardního odhalování chyb. Chybějící středník Středník v jazyce Pascal odděluje jednotlivé příkazy. V případě vynechání středníku za příkazem vypíší všechny překladače prakticky shodná chybová hlášení – ;expected. Free Pascal k dané chybě doplní ;expected bud identifier found. Nedeklarovaná proměnná Zde se liší Virtual Pascal a Free Pascal od ostatních překladačů, které kromě aktuální umístění chyby vypíší v rámci chybové hlášky i nenadeklarovaný identifikátor. Virtual Pascal doplní ještě vizuální označení. program expressionTest; var a, b : integer; {c: integer} begin a := 3; b := a* 4; c := (b + a)/2; end.
38
5
TESTOVÁNÍ VLASTNOSTÍ PŘEKLADAČŮ
Záměna operátoru přiřazení Při záměně operátoru všechny překladače při překladu oznámí chybu a označí řádek, na kterém chyba vznikla. Použití jiných uvozovek ve výpisu textového řetězce Častou chybou převzatou z jiných programovacích jazyků jsou jiné typy uvozovek, které se používají v ostatních programovacích jazycích. Zde pouze Irie Pascal dovede korektně přeložit, ostatní překladače již při překladu vyhodí chybové hlášení. begin a := 3; b := a* 4; c := (b + a)/2; write ("Výsledek výrazu je", c); {jiné uvozovky} end. Mimo rozsah pole Je definováno pole o dvou položkách a v programu je simulován pokus výpisu také třetí nedefinované položky pole. Zde byly rozdíly poměrně velké. Kompilátory Turbo Pascal a Virtual Pascal oznámily chybu již při překladu kódu srozumitelným hlášením. U Irie Pascalu proběhl překlad bez chyby, ale při spuštění výstupního programu aplikace zhavaruje a oznámí chybu. Free Pascal při překladu zobrazí jen varování a popis chyby. Aplikace se přeloží, spustí a vypíše i danou položku mimo rozsah. program arrayTest; var m : array[1..2] of integer; begin m[1] := 1; m[2] := 2; m[3] := 3; write(m[1]); write(m[2]); write(m[3]); end.
5.4
Syntaktické a sémantické chyby
39
Sémantické chyby Typickým příkladem sémantické chyby ve zdrojovém kódu je nedodržení datového typu při operacích s proměnnými. Simulace chyby spočívá při pokusu sčítání proměnné typu integer s proměnnou typu string. program semantika; var a: integer; var b: string; {chybně deklarovaná proměnná b} var c: integer; begin readln(a); readln(b); c:=a+b; writeln(c); end. Jazyk C Chybějící středník za příkazem Jako první test byl pro zjištění zpětné vazby na syntaktickou chybu použit vzorek, ve kterém chyběl ukončovací středník příkazu. Všechny překladače označí číslem řádku, ve kterém je chyba. Clang a Nwcc pak přehledněji vypíší daný úsek kódu s chybou, Clang navíc přidá barevné označení. Nejchudší výpis má pak překladač Tiny CC. Prvek mimo rozsah pole Obdobně jako v jazyce Pascal byl kompilátorům ve standardním nastavení předložen vzorek, kde se předkládá poli více prvků, než bylo deklarované. Překladače Nwcc a Tcc vypíší při kompilaci chybu, Clang a GCC zobrazí pouze varování, ale překlad povolí. Srozumitelností zpětné vazby je na tom z testovaných překladačů nejlépe Clang a Nwcc. Tiny CC vypíše chybovou hlášku index too large, bohužel nelze na první pohled zjistit, zda se jedná pouze o varování nebo chybu. Nedeklarovaná proměnná Pro nenadeklarovanou proměnou, která je poté použita v hlavní funkci main (), je vypsáno všemi testovanými překladači téměř shodné chybové hlášení. Nejpřesnější chybový výstup poskytne překladač GCC a Clang.
40
5
TESTOVÁNÍ VLASTNOSTÍ PŘEKLADAČŮ
Shrnutí Tabulka 3 zobrazuje výsledky testů reakcí na syntaktické chyby prováděných na překladačích jazyka Pascal. Tab. 3: Shrnutí výsledků testů – Pascal Chybějící ukončení příkazu Free Pascal Irie Pascal Virtual Pascal Turbo Pascal
fatal error - ; expected but identifier write found error ; expected ; expected ; expected Nenadeklarovaná proměnná
Free Pascal Irie Pascal Virtual Pascal Turbo Pascal
identifier not found (d) variable expected unknown identifier (d) Error 3 - unknown identifier Záměna operátoru přiřazení
Free Pascal Irie Pascal Virtual Pascal Turbo Pascal
error: illegal expression := expected error 91 := expected error 91 := expected Záměna uvozovek
Free Pascal Irie Pascal Virtual Pascal Turbo Pascal
illegal character OK syntax error 5 error 5 syntax error Mimo rozsah pole
Free Pascal Warning: range check error while evaluating constants Irie Pascal Při spuštění: out of range Virtual Pascal error out of range Turbo Pascal error: constant out of range
Z pohledu testu sémantické chyby na daném vzorku poskytuje nejlepší výstup Free Pascal, který sdělí, o jakou operaci se programátor pokouší. Ostatní překladače vypíší pouze hlášení type mismatch.
5.4
41
Syntaktické a sémantické chyby
Tabulka 4 zobrazuje výsledky testů reakcí na syntaktické chyby prováděných na překladačích jazyka C. Tab. 4: Shrnutí výsledků testů – Jazyk C Chybějící ukončení příkazu GCC 4.5.2 Tiny CC Nwcc Clang 2.8 Pelles C Lcc-win
error: expected ; before ’c’ ; expected (8) Error: Parse error at c(#2) ; expected expected ’;’ but found ’c’ Syntax error; missing semicolon before ’c’ Nenadeklarovaná proměnná
GCC Tiny CC Nwcc Clang Pelles C Lcc-win
error: ’c’ undeclared (first use in this function) ; ’c’ undeclared Undeclared identifier ’c’ ; expected Undeclared identifier ’c’. Undeclared identifier ’c’. Prvek mimo rozsah pole
GCC Tiny CC Nwcc Clang Pelles C Lcc-win
warning: excess elements in array initializer index too large Error: Initializer for aggregate type too big warning: excess elements in array initializer Undeclared identifier ’c’ Too many initializers
U testování reakcí na sémantické chyby v jazyce C se výpisy jednotlivých překladačů od sebe liší. Ve standardním nastavením překladače všechny zobrazí pouze varování na úrovni warning, že se jedná o chybnou operaci. Při pokusu o spuštění programu se zobrazí při výpisu chybný výsledek. int a, b, c; int main(void) { a = "ahoj"; b = 6 ; c = a + b; return (0); }
42
5
TESTOVÁNÍ VLASTNOSTÍ PŘEKLADAČŮ
Tab. 5: Nedodržení datového typu Chybové hlášení
Informace během spouštění
GCC
assignment makes integer from pointer without a cast
chybný výsledek
Clang
incompatible pointer to integer conversion
chybný výsledek
Tiny CC assignment makes integer from pointer without a cast
chybný výsledek
Nwcc
assignment from non-arithmetic to arithmetic type
chybný výsledek
Lcc-win
illegal types integer and pointer to char
nelze spustit
Pelles C
incompatible types int and char
nelze spustit
5.5
Běhové a logické chyby
Jako příklad logické běhové chyby, která se projeví až po spuštění programu, je dělitelnost nulou. Překlad proběhne korektně, protože v kódu není žádná syntaktická chyba, ovšem při vykonání kritické částí kódu program skončí v chybovém stavu. Irie Pascal a Turbo Pascal přesně definují, k jakému problému došlo, kdežto překladače Free Pascal a Virtual Pascal oznámí pouze číslo chyby, kterou je nutné dohledat v dokumentaci daného překladače. Vzhledem k tomu, že jazyk Pascal je přísně typový, nehrozí zde problém nabytí nečekané hodnoty proměnné při běhu programu. I překladače jazyka C byly otestovány na logickou běhovou chybu, kde byl použit výraz dělení nulou. Zde všechny překladače kód přeložily, ale při pokusu o spuštění programu se objevil chybový výpis: Výjimka v pohyblivé řádové čárce (SIGFPE) # include <stdio.h> int a, b, c; int main(void) { a = 2; b = 0; c = a/b; {kritické místo} printf("vysledek je %d" ,c); }
5.6
Paměťová a časová náročnost
Další kapitola diplomové práce se zabývá experimentální paměťovou a časovou náročností samotného překladače. U algoritmu se dá určit časová a prostorová složitost algoritmu, která může být lineární, konstantní atd. Jakým způsobem zjišťovat náročnost u překladačů? U prostorové náročnosti lze hodnotit výslednou velikost byte kód, který překladač po kompilaci produkuje. Dalším kritériem bude nesporně velikost výsledného binárního programu. Srovnání má logicky smysl na stejné platformě
5.6
43
Paměťová a časová náročnost
a pouze pod totožným operačním systémem, aby dané výsledky byly relevantní. Pro eliminaci nepřesností a odchylek měření, je každý pokus prováděn několikrát a následně je uváděna průměrná hodnota z daných měření. Utility, které měří čas a operační paměť jednotlivých překladů, byly spouštěny za stejných podmínek z důvodu objektivity měření daných veličin. Prvním testem je test časové náročnosti překladu jazyka Pascal. Měřen je tedy čas překladu včetně linkování. Doba překladu závisí na velikosti zdrojového souboru. Čím větší je počet řádků, tím delší je doba překladu a linkování. Kromě času překladu bylo testováno, zda si překladače poradí s relativně nestandardním vzorkem. Daným vzorkem je použit soubor, který má 5000 řádků. Vzorek zpracovává jednoduchý příkaz v hlavní funkci testovacího programu. Z prvního testování lze zjistit, že velmi dobře je na tom komerční Irie Pascal, naopak nejhůře vychází kompilátor Free Pascal, který generuje největší čas. S takovou velikostí zdrojového kódu si neporadil překladač Turbo Pascal, u Irie Pascalu nebylo možné ve zkušební verzi generovat výsledný kód. Časy překladu jsou uvedeny včetně linkování. Tab. 6: Vzorek: 5000 řádků v hlavní funkci Čas překladu (s)
Velikost EXE souboru (B)
Free Pascal
3,81
230 182
Irie Pascal
0,14
Nelze vygenerovat EXE
Turbo Pascal
Error: Statement too large
–
Virtual Pascal
0,30
207 360
Jako další vzorek byl použit jednoduchý algoritmus na výpočet dělitelnosti. Tentokrát se jedná o reálný program, který může být použit v praxi. program delitelnost; var cislo, a: Integer; begin writeln(’Rekni mi cislo:’); readln(cislo); for a := 2 to 100 do begin if cislo mod a = 0 then writeln(’Cislo ’,cislo, ’ je delitelne ’,a,’.’); end; end. Je dobré si povšimnout, že mezi časy překladu a také i mezi velikostmi výsledných binárních souborů jsou značné rozdíly. Záleží, zda vývojář preferuje lepší rychlost překladu, nebo je potřeba pro úsporu paměti zajistit co nejmenší výsledný binární spustitelný soubor.
44
5
TESTOVÁNÍ VLASTNOSTÍ PŘEKLADAČŮ
Tab. 7: Čas překladu a velikost binárního souboru Čas překladu (s) Velikost EXE souboru (B) Free Pascal
0,34
57 550
Irie Pascal
0,04
37 494
Turbo Pascal
0,21
2 928
Virtual Pascal
0,12
16 384
Dalším sledovaným parametrem u paměťové náročnosti je využití operační paměti po spuštění EXE souboru v CLI (command line). Opět jsou použity průměrné hodnoty – program je několikrát spuštěn a je uveden průměr z pěti spuštění. K tomuto účelu byl využit vzorek programu pro výpočet úroků. Následující tabulka poskytne přehled výsledků daných kompilátorů. Zatížení paměti je zaznamenáno ve správci procesů systému Windows, odkud jsou hodnoty odečítány. Tab. 8: Zatížení operační paměti Využití paměti RAM (KB) Free Pascal
448
Irie Pascal
536
Turbo Pascal Virtual Pascal
1 072 272
Z výše uvedeného testu vyplývá, že RAM paměť nejméně zatěžují výstupní binární soubory vývojového prostředí Virtual Pascal. Pro objektivitu měření byly provedeny testy na více vzorcích a bylo dosaženo obdobných výsledků. Velká paměťová náročnost Turbo Pascalu vyplývá ze spuštění 16bitového subsystému, ve kterém daná aplikace běží. Ve správce procesů lze spuštěný proces najít pod názvem ntvdm.exe. Pro jazyk C byly stanoveny obdobné testovací mechanismy jako u jazyka Pascal. Jako první vzorek pro určení časové a prostorové složitosti kompilátorů byl vyroben vzorek o 10 000 řádků, kde se opakuje příkaz výpisu ve funkci main – tedy obdoba jako v jazyce Pascal. Pro spuštění kompilace bez linkování do výsledného souboru slouží u všech překladačů přepínač -c. Sledované parametry: • kompilace, • kompilace včetně slinkování, • velikost binárního souboru.
5.6
45
Paměťová a časová náročnost
Tab. 9: Výkon překladačů jazyka C Kompilace (s) Kompilace + linkování (s) Velikost binárního souboru (B) GCC
2,840
2,880
134 114
Clang
0,540
0,580
187 362
Tiny CC
0,040
0,040
202 972
Nwcc
0,280
0,320
167 001
Pelles C
0,476
0,930
153 088
Lcc-win
1,861
2,100
348 910
Po následujícím testu na OS Linux Mint je zřejmé, že Tiny CC dosahuje nejlepšího času z testovaných unixových překladačů. Nejmenší binární soubor produkuje naopak překladač GCC, u kterého trvá kompilace nejdelší čas. V případě dvou testovaných překladačů pod OS Windows vykazuje lepší výsledky ve všech směrech Pelles C. Pro testování a ověření předchozí časové a paměťové náročnosti nejlépe poslouží kompilace reálného projektu. Další vzorek pro testování byl použit program Vim. Jedná se o konzolový unixový textový editor, který je využíván zejména mezi vývojáři a programátory. Kompilován byl Vim ve verzi 73 se zdrojovými soubory o velikosti 16 MB. U jednotlivých překladačů byl testován čas kompilace, velikost binárního výsledného souboru a poté využití operační paměti systému textového editoru. Kompilace při nastavení vhodné direktivy proběhla v pořádku kromě překladače Tiny CC, který se neúspěšně snažil najít knihovnu v jiném umístění. Problém byl však vyřešen. Kompilace a instalace textového editoru proběhla standardním způsobem pomocí utility Make. Byly použity následující příkazy: CC={vybrany prekladac} ./configure // spuštění konfiguračního skriptu make // spuštění utility make make install // instalace do adresářové struktury systému Při spouštění konfiguračního skriptu je potřeba definovat daný kompilátor v parametru. V případě jeho nedefinování se spouští výchozí systémový kompilátor. Výchozí kompilátor lze změnit i v souboru Makefile.in, jedná se však o nedoporučovanou možnost. Tab. 10: Výkon překladačů jazyka C Kompilace Velikost binárního Využití paměti + linkování (s) souboru (B) RAM (kB) GCC
84
1 390 712
2 100
Clang
53
1 411 336
2 356
4
1 817 456
–
13
2 625 140
2 276
Tiny CC Nwcc
46
5
TESTOVÁNÍ VLASTNOSTÍ PŘEKLADAČŮ
Z výsledku vyplývá, že nejdelší čas spotřebuje pro kompilaci a linkování překladač GCC 4.5.2, naopak nejkratší čas je zaznamenán u překladače Tiny CC. Z testu je dále patrné, že vyšší rychlost překladu je vykoupena narůstající velikostí výsledného binárního souboru, konkrétně v případě překladače Nwcc. Při překladu pomocí kompilátoru Tiny CC se vyskytla následující chybová hláška: /usr/lib/libncurses.so: referenced dll ’libdl.so.2’ not found tcc: undefined symbol ’dlerror’ make[1]: *** [vim] Error 1 make[1]: Leaving directory ‘/home/stratos/vzorky.c/vim73/src’ make: *** [first] Error 2 Po vyřešení problému s chybnou referencí knihovny se překlad dokončil úspěšně. Instalace pomocí make install neproběhla korektně, a tak z důvodu objektivity testu není uvedena hodnota obsazení paměti RAM u daného kompilátoru, i když se podařilo textový editor úspěšně zkompilovat.
5.7
Efektivita strojového kódu
Další zkoumanou vlastností je efektivita strojového kódu. Jakým způsobem efektivitu měřit? Bezesporu se dá efektivita kódu označit časem vykonání jistého příkazu. Jako vzorek byl vyroben jednoduchý program na kopírování souborů – obdoba linuxového příkazu cp. Poté byla následně měřena doba provádění procesu pomocí příkazu time. I když jako argument byl použit soubor o velikost 950 MB, čas provádění byl ve všech případech stejný. Další možností, která se nabízí, je měřit procesorový čas, který je spotřebován za běhu programu. Funkce clock() nevrací hodnoty času v sekundách ale v ticích procesoru. Pro převedení této hodnoty na sekundy je třeba ji ještě vydělit příslušnou konstantou. Jméno konstanty se v závislosti na daném překladači může lišit. Nejčastěji se používá konstanta CLOCK PER SEC, která je použita v následujícím kódu. Typické použití v jazyce C zobrazuje následující kód: #include
clock_t start, end; double elapsed; start = clock(); ... /* Měřené příkazy*/ end = clock(); elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; Aby byla byla daná funkce správně spuštěna, je třeba připojit ke zdrojovému kódu hlavičkový soubor time.h, který podporuje časové funkce. Za účely testů je použit vzorek, který po určeném počtu opakování vypíše každý průchod. Tedy je nadefinováno 1 000 000 opakování a změřen procesorový čas. Na daný algoritmus spotřebují výstupní soubory všech linuxových překladačů zhruba shodný čas.
5.7
47
Efektivita strojového kódu
Tab. 11: Testování efektivity kódu Procesorový čas (s) Doba trvání procesu (s) GCC
3,54
43,0
Tiny CC
3,61
44,0
Clang
3,61
43,0
Nwcc
3,61
43,0
Pelles C
130,60
130,6
Lcc-win
–
128,0
U jazyku Pascal byl proveden obdobný test pro cyklus for s opakováním. Pro jazyk Pascal bylo měření problematičtější. Funkce clock(), použita v jazyce C, není dostupná pro jazyk Pascal. Bylo tedy nutné hledat jiné řešení. Pro jazyk Pascal byla vybrána funkce gettime(). Výstupem této funkce je aktuální čas s přesností na sekundy. Funkce gettime() byla zavolána celkově dvakrát – na začátku měření a na konci měření. Rozdíl časů je pak výsledná doba, po kterou je zpracovávána vybraná část zdrojového kódu. Funkce gettime() je součástí modulu DOS a UNIX. Vzhledem k testování překladačů jazyka Pascal pod OS Windows, byl zvolen modul DOS. Ověření správnosti proběhlo ještě za pomocí utility timeit, která slouží k měření doby daného procesu. Pro Virtual Pascal nebyla funkce gettime() k dispozici. Ukázka kódu v jazyce Pascal: procedure StartClock; {definice startu procedury} begin gettime (hr,mins,se,s1); end; procedure StopClock; var siz : longint; hr2, min2, se2 : word; begin GetTime (hr2, min2, se2, s1); siz := se2-se+(min2-mins)*60+(hr2-hr)*60*60; {rozdil casu} writeln(siz,’ seconds’); end; begin StartClock; for i := 1 to 100000 do writeln(’Cyklus cislo’ ,i); StopClock; end.
48
5
TESTOVÁNÍ VLASTNOSTÍ PŘEKLADAČŮ
Tab. 12: Testování efektivity kódu Procesorový čas (s) Doba trvání procesu (s)
5.8
Free Pascal
9,5
9,5
Irie Pascal
18,0
18,0
Turbo Pascal
7,0
7,0
Virtual Pascal
–
9,3
Dokumentace a podpora
Dokumentace a podpora je také nedílnou součástí softwarového produktu. Kvalitní produkt by měl obsahovat nejen dobrou uživatelskou nápovědu, nýbrž také technickou a provozní dokumentaci. Dokumentace může být buď jako samostatná příručka, nebo také součástí programu v podobě nápovědy. Dokumentaci lze rozdělit do několika kategorií: • dokumentace požadavků, • dokumentace architektury/designu, • technická dokumentace, • uživatelská dokumentace, • marketingová dokumentace. Virtual Pascal Instalace překladače Virtual Pascal probíhala standardně jako běžná aplikace MS Windows. Vzhledem k tomu, že oficiální vývoj překladače byl již ukončen v roce 2005, tak zmizely i původní stránky překladače. Po ukončení oficiálního vývoje je nadále neoficiálně podporován a na webu lze nalézt dokumentaci v PDF, která není pouze referenční příručkou, nýbrž relativně čtivým materiálem pro programátory používající Virtual Pascal. Výše zmíněná příručka je součástí instalace Virtual Pascalu. Součástí integrovaného prostředí je podrobná nápověda přímo v aplikaci. Free Pascal Free Pascal je prakticky jediný překladač vyvíjen až do dnešní doby. Nabízí instalaci buď samotného kompilátoru v příkazovém řádku, nebo možnost s IDE. Dokumentace a popis Free Pascalu lze najít na webu, kam odkazuje i oficiální nápověda. Na webu http://www.freepascal.org/docs.var lze najít kromě uživatelské nápovědy, také nápovědu pro programátory, referenční příručku překladače i knihoven. Všechny příručky je možno získat ve formátu PDF. Za poplatek je dostupný také překlad do německého jazyka.
5.8
Dokumentace a podpora
49
Turbo Pascal Turbo Pascal se spouští v 16-bitovém subsystému, protože byl navržen pro systém MS DOS. Informace a popis jazyka Turbo Pascal lze dohledat na webu http://turbopascal.org/, kde nalezneme jak popis produktu, tak i ukázkové příklady v Pascalu. Součástí IDE je nápověda, která zahrnuje referenční příručku jazyka a je dostupná i v českém jazyce. Irie Pascal Na webových stránkách Irie Pascalu je ke stažení zkušební verze Irie Pascalu, která byla otestována. Součástí integrovaného rozhraní je klasická forma nápovědy windows aplikací. Na adrese http://www.irietools.com/iriepascal/windows/user.html je k dispozici ke stažení HTML a PDF verze uživatelské příručky a také readme soubor, který zahrnuje krátký popis produktu včetně systémových požadavků na provoz. GCC Dokumentaci k překladači lze nalézt na jejich stránkách http://gcc.gnu.org/, kde se nabízí ke stažení verze ve formátu HTML i PDF. Dále kromě manuálových stránek zde nalezneme návod na instalaci a konfiguraci překladače pro různé platformy a přehledně zpracovanou Wiki stránku. Dokumentace k celému projektu je značně rozsáhlá a jsou zpracovány všechny možnosti nastavení překladače. Nevýhodou je dostupnost veškerých textů pouze v anglickém jazyce. Speciální instalace nebyla nutná, protože GCC již bylo obsaženo v testovací distribuci Linux Mint. Clang U překladače Clang nalezneme opět kompletní dokumentaci on-line – na webových stránkách http://clang.llvm.org/docs/UsersManual.html. Vzhledem k tomu, že se jedná o plnohodnotnou náhradu překladače GCC, lze využít velkou část jeho přepínačů a možností. Clang je součástí použité linuxové distribuce, proto stačí instalace z repozitáře systému. Na webu o překladači se nachází sekce Release Notes, kde najdeme změny mezi jednotlivými verzemi kompilátoru. Nwcc Nwcc není již součástí linuxové distribuce Linux Mint. Lze ho získat na oficiálním webu ve formě zdrojového kódu. Kompilace probíhá standardně - nejprve je spuštěn skript ./configure poté je vygenerován soubor makefile a standardně pomocí make zkompilujeme. Kompilace několikrát zhavarovala na chybějících knihovnách a utilitách. První pokus skončil chybovým výpisem cannot find /usr/lib/libc.so Naštěstí chybová hlášení překladače GCC byla v daném případě srozumitelná a vždy bylo jasné, na které chybě kompilace skončila. Po čase hledání na webu a kompilaci
50
5
TESTOVÁNÍ VLASTNOSTÍ PŘEKLADAČŮ
dodatečných modulů a instalaci potřebných utilit z repozitářů již kompilace proběhla v pořádku. Součástí instalačního balíčku je soubor readme, kde jsou základní instalační instrukce. Ucelenou dokumentaci k překladači bohužel nenajdeme. Na webových stránkách lze nalézt informace o vlastnostech překladače, testy kompilací, porovnání s kompilátorem GCC, ale ucelený manuál chybí. Po standardní kompilaci překladače nejsou dostupné ani manuálové stránky systému. Tiny CC Nejnovější verze překladače Tiny CC se nacházela v repozitářích linuxové distribuce Linux Mint a tudíž opět nebyla jeho instalace nijak obtížná. Rozsáhlou referenční příručku lze nalézt na webu http://bellard.org/tcc/tcc-doc.html. Po zadání příkazu tcc bez parametrů se vypíše seznam možných přepínačů překladače a v případě zadání příkazu man tcc se zobrazí offline dokumentace v podobě manuálových stránek. Lcc-win Lcc-win nabízí samotnou referenční příručku jazyka v nápovědě, které je IDE prostředí. Na webu se nachází kompletní dokumentace včetně zdokumentovaného WINAPI. Pelles C Pelles C obsahuje rovněž nápovědu v OS Windows, kde jsou podrobně popsány všechny součásti IDE prostředí včetně jejich funkcí. Další podporu poskytuje Pelles C Wiki http://wiki.pellesc.de/doku.php, kde je dopodrobna rozebrána obrázková instalace překladače včetně programování ve WINAPI.
5.9
Specifika daného jazyka
V této sekci se práce zabývá podporou specifických vlastností překladačů pro daný jazyk. U jazyka C byla zkoumána podpora implementace standardu C99, který byl následně v březnu 2000 přijat i jako ANSI standard. U řady zdrojů se uvádí u některých překladačů částečná podpora dané specifikace, překladače jsou otestovány na vybrané prvky standardu C99. Standard například doplňuje podporu řádkových komentářů – tzv. on-line mód, dále přidává podporu knihovny tgmath.h. Také zavádí klíčové slovo restrict, které v deklaraci ukazatele specifikuje, že na paměť odkazovanou tímto ukazatelem nepřistupuje už žádný jiný ukazatel.
5.9
51
Specifika daného jazyka
Testované prvky standardu C99: • podpora řádkových komentářů //komentář, • podpora knihovny tgmath.h, • proměnná long long int, • klíčové slovo restrict. Tab. 13: Podpora standardu C99 in-line komentáře knihovna tgmath.h operátor long long int
restrict
GCC
ANO
ANO
ANO
-std=c99
Tiny CC
ANO
NE
ANO
ANO
Clang
ANO
ANO
ANO
ANO
Nwcc
ANO
NE
ANO
ANO
Pelles C
ANO
ANO
ANO
ANO
Lcc-win
ANO
ANO
ANO
ANO
U jazyka Pascal lze zajisté testovat též řadu specifik a vlastností, pro účely byla vybrána podpora objektů implementačního rozšíření Turbo Pascalu a také objektů, které jsou používány v jazyce Delphi, který je v současnosti hojně používaný. U překladačů jazyka Pascal byly tedy zkoumány tyto vlastnosti: • podpora objektů Deplhi class, • podpora objektů Turbo Pascalu. type Vypis = class {definice objektů implementací jazyka Delphi} procedure Put; end; ... procedure Vypis.Put; begin WriteLn(’Dobry den’); end; Tab. 14: Objekty v Pascalu Turbo Pascal Delphi Free Pascal
ANO
NE
Irie Pascal
NE
NE
Turbo Pascal
ANO
NE
Virtual Pascal
ANO
ANO
52
6
6
SHRNUTÍ A INTERPRETACE VÝSLEDKŮ
Shrnutí a interpretace výsledků
V předchozí kapitole diplomové práce bylo provedeno testování jednotlivých překladačů dle vybraných kritérií a výsledky každého testu jsou zobrazeny a okomentovány přímo u dané kapitoly. V následujícím textu jsou předchozí výsledky přehledně shrnuty a interpretovány. Některé výsledky jsou pro přehlednost interpretovány formou grafů, které se vždy vážou k testovacímu vzorku, který je popsán v příslušné části kapitoly Testování vlastností překladačů.
6.1
Časová a paměťová náročnost
U jazyku Pascal byly překladače testovány podle čtyř kritérií: • čas překladu, • velikost binárního souboru, • vytížení operační paměti výstupním programem, • délka provádění úseku strojového kódu. Testy paměťových a časových náročností byly provedeny z různých hledisek a kritérií. Testování přineslo bezpochyby zajímavé výsledky. Mezi jednotlivými překladači byly poměrně velké rozdíly, které jsou na grafu dobře patrné. Co ale z testů vyplývá? Základní otázka, která se nabízí, jsou opravdu všechna kritéria důležitá pro praxi? Z toho důvodu jsou výsledky rozděleny samostatně jak pro Pascal, tak pro jazyk C. Každý jazyk má jiná specifika a je nutné udělat rozbor každého zvlášť. Zdrojové programy v Pascalu jsou slouží většinou pro výuku, nebo řeší konkrétní problém menšího rozsahu. Jazyk Pascal není vhodný pro velké projekty – naopak, pokud vývojář žádá nenáročný program na systémové prostředky, může být Pascal správná volba. Kritérium času překladu lze z toho důvodu zařadit k těm méně podstatným a nemá v tomto ohledu příliš praktický význam. Naopak mezi důležitá kritéria by měla být považována efektivita výsledného kódu, která byla v testu demonstrována na mnohokrát opakujícím se cyklu for(). Zde nejlepších výsledků dosahovaly bezpochyby překladače Virtual Pascal a Free Pascal. Z hlediska velikosti výsledného souboru, kde je cílem generování co nejmenšího binárního souboru, boduje překladač Turbo Pascal. Tato výhoda Turbo Pascalu je ovšem vykoupena větším zatížením operační paměti z důvodu nutnosti běhu šestnáctibitového subsystému, kde se projeví tato nevýhoda zejména při spouštění malých prográmků pod operačním systémem Windows 7.
53
Časová a paměťová náročnost
Spotřebovaný čas (s)
6.1
20 18 16 14 12 10 8 6 4 2 0
Free Pascal
Irie Pascal
Virtual Pascal Turbo Pascal
Překladače Spotřebovaný čas (s)
Obr. 3: Pascal – Čas překladu vybraného vzorku
70000
Velikost souboru (B)
60000 50000 40000 30000 20000 10000 0
Free Pascal
Irie Pascal
Virtual Pascal Turbo Pascal
Překladače Velikost souboru (B)
Obr. 4: Pascal – Velikost výstupního souboru
54
6
SHRNUTÍ A INTERPRETACE VÝSLEDKŮ
1200
Spotřebovaná paměť (kB)
1000 800 600 400 200 0
Free Pascal
Irie Pascal
Virtual Pascal
Turbo Pascal
Překladače
Spotřeba operační paměti (kB)
Obr. 5: Pascal – Vytížení operační paměti
Spotřebovaný čas (s)
20 15 10 5 0
Free Pascal
Irie Pascal
Virtual Pascal Turbo Pascal
Překladače
Spotřebovaný čas (s)
Obr. 6: Pascal – Efektivita kódu
6.1
55
Časová a paměťová náročnost
U jazyka C byla při testování paměťové náročnosti hodnocena tato kritéria: • čas překladu, • čas překladu včetně linkování, • kompilace většího projektu, • vytížení operační paměti výstupním programem, • délka provádění úseku strojového kódu. Na rozdíl od jazyka Pascal se jazyk C uplatňuje ve velkých projektech a jsou běžně překládány tisíce zdrojových souboru – např. při kompilaci linuxového jádra nebo Apache. Zde nabývá důrazu čas kompilace a linkování, kdy je třeba přilinkovat v některých případech velké množství knihoven. Na prvním grafu je zobrazen čas překladu zdrojového souboru v jednom případě a v druhém případě včetně linkování. Opět jsou patrné velmi výrazné rozdíly. Excelentních výsledků dosahuje překladač Tiny CC, který jak v tomto testu vykázal nejmenší čas překladu vůči ostatním překladačům, tak v překladu většího projektu (program Vim). U překladačů testovaných pod OS Linux se linkování výraznou měrou nepodílelo na celkovém času překladu vybraného vzorku. Je zde vidět, že u obou překladačů testovaných pod Windows (Pelles C, Lcc-win) mělo volání linkeru a samotné linkování větší podíl na času překladu. Obecně lze těmito testy potvrdit, že ve srovnání s ostatními překladači dosahují překladače Tiny CC a Nwcc nejlepších výsledků. Z hlediska efektivity kódu jsou zde vidět velké rozdíly mezi výslednými programy generovanými překladači OS Windows a Linux. Zde je patrná souvislost s operačním systémem a ukazuje se, že daný vzorek je výrazně efektivnější na linuxovém systému. 3,5 3
Čas (s)
2,5 2 1,5 1 0,5 0
Gcc
Clang
Nwcc Tiny CC Pelles C Lcc-win Překladače
Kompilace
Obr. 7: C – Časová náročnost překladu
Kompilace + Linkování
56
6
SHRNUTÍ A INTERPRETACE VÝSLEDKŮ
400000
Velikost souboru (B)
350000 300000 250000 200000 150000 100000 50000 0
Gcc
Clang
Nwcc
Tiny CC Pelles C Lcc-win
Překladač Velikost souboru (B)
Obr. 8: C – Velikost výstupního souboru
140 120
Čas (s)
100 80 60 40 20 0
Gcc
Clang
Nwcc Tiny CC Pelles C Lcc-win Překladače
Procesorový čas
Obr. 9: C – Efektivita kódu
Čas behu programu
6.2
6.2
Reakce na chyby
57
Reakce na chyby
Zvolené překladače byly testovány na syntaktické, sémantické, běhové a logické chyby. Výsledky byly hodnoceny dle srozumitelnosti výsledného chybové hlášení. Čím přesnější je označení daného typu chyby, tím rychleji je chyba programátorem detekována a odstraněna. Testovat překladače na jednu syntaktickou nebo sémantickou chybu by bylo nedostatečné, proto bylo simulováno několik nejčastějších chyb: • chybějící oddělovač příkazů, • použití nedeklarované proměnné, • výpis nenadeklarované položky pole, • záměna operátoru přiřazení, • použití jiných uvozovek ve výpisu textového řetězce. Z pascalovských překladačů vyniká Virtual Pascal, který kromě chybového výpisu zobrazí ještě barevné vyznačení chyby a část kódu v ladícím okně, kde se chyba nalézá. Nejméně přesná chybová hlášení poskytuje naopak Irie Pascal, chybový výpis je relativně nepřehledný. U jazyka C díky barevně zvýrazněné syntaxi vyniká linuxový překladač Clang a zároveň poskytuje velmi přesné a srozumitelné výsledky. Dle testů nejhůře dopadl překladač Tiny CC, který se omezuje na stručnější chybová hlášení. V přesnosti chybového výstupu poskytly překladače Pelles C a Lcc-win pod OS Windows též podrobný výpis. Z hlediska testu na sémantickou chybu sčítání dvou proměnných různých typů dopadl nejlépe Free Pascal, který vypsal konkrétní chybová hlášení včetně informace, o co se programátor pokouší. Z logických a běhových chyb byl vybrán reprezentativní vzorek dělitelnost nulou a zkoumána reakce překladačů. Vzhledem k tomu, že ve vzorku není žádná syntaktická chyba, překlad se provede správně a chyba se projeví až při vykonání inkriminované části kódu. Přesný typ chyby byl generován pouze z překladačů Irie Pascal a Turbo Pascal.
6.3
Dokumentace
U překladačů byla testována: • instalační instrukce (soubor README), • dostupnost příručky (manuál, referenční příručka), • nápověda v aplikaci. V hodnocení dokumentace prakticky všechny hodnocené překladače uspěly a obsahovaly tak požadovanou dokumentaci k instalaci i používání. Výjimku tvoří překladač Nwcc, kde nebyly po kompilaci dostupné manuálové stránky v aplikaci. Ani oficiální web neodkazuje na podrobnou dokumentaci nebo referenční příručku. To pravděpodobně souvisí se skutečností, že projekt Nwcc není tak rozsáhlý jako ostatní překladače.
58
6
SHRNUTÍ A INTERPRETACE VÝSLEDKŮ
U hodnocených překladačů Pascalu je výsledek dobrý. Free Pascal zahrnuje i wiki stránky, kde mohou přispívat a návody upravovat sami uživatelé. Pro Virtual Pascal existuje i on-line neoficiální příručka, která slouží jako výukový materiál.
6.4
Podpora vybraných prvků jazyka
U překladačů byla testována: • Pascal: podpora Object Pascalu ve dvou implementacích, • Jazyk C: podpora vybraných prvků standardu C99. Překladače jazyka C uspěly v podpoře vybraných prvků standardu C99 s výjimkou Nwcc a Tiny CC, které nemají podporu knihovny tgmath. Podporu Object Pascalu má v obou testovaných implementacích pouze překladač Virtual Pascal, který z daného testu vyšel jako jasný vítěz, a tak ho lze použít i programátory, kteří jsou zvyklí na syntaxi jazyka Delphi.
7
7
DISKUSE
59
Diskuse
Problematika překladačů a programovacích jazyků je relativně obtížná a komplexní. Ke zpracování diplomové práce bylo nutné mít řadu znalostí z oblastí překladačů, programovacích jazyků, algoritmizace i operačních systémů. Dobrý základ přinesla taktéž práce Schopnosti překladačů objektových jazyků od Martina Ventruby. (Ventruba, 2011) V diplomové práci byly srovnány vybrané a používané překladače jazyka C a Pascal z různých úhlů pohledů. Jaký překladač poskytuje nejlepší vlastnosti a který naopak v daných testech propadl? Na tuto otázku neexistuje jednoznačná odpověď. Po testování a zhodnocení není možné konstatovat, že ten daný překladač propadl ve všech testech a jiného zase favorizovat jako nejlepšího ze všech. Každý testovaný překladač má jiné parametry a vyznačuje se specifickými vlastnostmi – v některých případech ne příliš zdůrazněnými v samotné dokumentaci či popisu překladače. Každý programátor nebo uživatel daného překladače nebo vývojového prostředí má na překladače zajisté jiné požadavky. Vývojář začátečník, učící se daný programovací jazyk, bude požadovat od daného softwaru jiné vlastnosti, než například pokročilý vývojář, píšící velké a rozsáhlé aplikace optimalizované pro výkon. Výsledky testů mohou tedy využít různé skupiny programátorů, kteří se budou rozhodovat, který překladač, popřípadě vývojové prostředí splní jejich očekávání při vývoji softwaru. U překladačů jazyka Pascal nabídl poměrně zajímavé vlastnosti překladač Virtual Pascal. Je vhodný pro začátečníky, kteří s Pascalem začínají. Jeho chybová konzole poskytuje přehledný barevný výstup a uživatelé jsou na chybu upozorněni jasnou a srozumitelnou interpretací chybového výstupu i podporou různých implementací objektového programování. Neoficiální součástí Virtual Pascalu je také elektronická výuková příručka. Pokud od překladače žádáme multiplatformní software s bohatou podporou, možností volby alternativního vývojového prostředí, tak lze doporučit Free Pascal. Z hlediska nativního IDE rozhraní pro OS Windows je dnes k dispozici jediný zástupce – Irie Pascal. V jednotlivých testech příliš neuspěl, ale pokud je žádán rychlý překlad zdrojového kódu či některé další doplňující vlastnosti překladače, je Irie Pascal vhodným kandidátem. Poněkud složitější situace je u překladačů jazyka C. Vzhledem k jeho užití v praxi vstupuje do hry také význam časové a paměťové náročnosti. Z hlediska uživatelů začátečníků bych v Linuxu doporučil sáhnout po překladači Clang, který poskytuje efektivní chybový výstup a disponuje poměrně dobře zpracovanou dokumentací. Pokud hledáme překladač, který je schopen velmi rychlé kompilace, je bezkonkurenčním favoritem překladač Tiny CC. Ani v případě maximální možné optimalizace jiných překladačů se nepodařilo tento výsledek překonat. Na úkor rychlosti však produkuje relativně velký výsledný binární kód. V případě potřeby malého výsledného souboru se ukázal jako nejvhodnější GCC překladač.
60
7
DISKUSE
Zajímavým poznatkem byl vliv výkonnosti výstupního kódu pod systémem Windows a Linux. Vzhledem k řadě optimalizacím jazyka C pro unixové systémy byl stejný kód na obou platformách v rychlosti diametrálně odlišný včetně INPUT a OUTPUT operací. Zde se projevuje skutečnost, že jazyk C je více optimalizován pro systémy UNIXu. Obdobně se překladače chovaly při linkování, kdy linkováním byl v operačním systému Windows spotřebován významně delší čas. Nejznámějším a nejpoužívanějším překladačem pro překlad unixových aplikací je bezesporu překladač GCC, který má bohatou komunitní podporu, pravidelné aktualizace a je používán širokým spektrem uživatelů. Menší projekty jako překladače Tiny CC, Clang nebo Nwcc cílí vždy na vylepšení konkrétní vlastnosti a parametrů překladu. Jazyk C v čisté podobě je využíván především pro psaní knihoven, síťových aplikací a dalších systémových aplikací. Zde je jasný rozdíl od Pascalu, který je využíván spíše začátečníky pro výuku programování a pochopení práce základních algoritmů. Bude jistě zajímavé, jakým směrem se bude vývoj překladačů ubírat do budoucna.
8
8
ZÁVĚR
61
Závěr
Práce hodnotila jednotlivé vlastnosti překladačů jazyka C a Pascal. Celkem bylo podrobeno testům šest překladačů jazyka C a čtyři překladače jazyka Pascal včetně jejich vývojových prostředí. Překladače byly srovnávány a hodnoceny z nejrůznějších kriterií. Práce obsahuje srovnání časové a paměťové náročnosti, hodnotí překladače v reakcích na nejrůznějších typy chyb nebo se zabývá dostupností a kvalitou dokumentace. Podrobnější analýza byla zpracována u paměťové a časové náročnosti překladů a výsledného kódu. Zkoumán byl čas překladu, velikost výsledného binárního souboru či zatížení operační paměti. U každého testu je popsán daný vzorek, který byl v testu použit a dále je interpretován výsledek a zhodnocení každého testu. Výsledky jsou zobrazeny ve formě tabulek u každého testu, nebo v případě časových a paměťových náročností ve formě přehledných grafů. Součástí testování a hodnocení bylo také využití a úprava existujících testovacích vzorků. V případě řady testů bylo nutné vytvořit vzorky vlastní.
62
9
9
LITERATURA
Literatura
Aho, V. A., Lam, S. M., Sethi, R., Ullmann, J. D. Compilers Compilers: Principles, Tech- niques, & Tools, Second Edition Boston: Pearson/Addison Wesley, 2007. 1009 s. ISBN 0-321-48681-1. Fowler, M. Refaktoring – Zlepšení existujícího kódu Grada Publishing, 2003. 396 s. ISBN 80-247-0299-1. Gries, D. Kompilátory číslicových počítačov Bratislava, 1981. 511 s. ISBN 63-558-81. Herout, P. Učebnice jazyka C České Budějovice, 1981. 280 s. ISBN 978-80-7232-351-7. Knuth, D. Umění programování: Základní algoritmy Computer Press, 2008. 672 s. ISBN 978-251-2025-5. Kreslíková, J., Martínek, D. Složitost algoritmů [on-line]. 2004. [cit. 22. 4. 2012]. Dokument ve formátu PDF. Dostupný na Internetu: http://jaja.kn.vutbr.cz/~belovic/IZP/8c_slozitost.pdf. Lacina, L. Překladače Pascalu [on-line]. 2010. [cit. 24. 4. 2012]. Dokument ve formátu HTML. Dostupný na Internetu: http://www.laaca.borec.cz/pascal.htm. Malý, M. Měření časových intervalů [on-line]. 2006. [cit. 25. 4. 2012]. Dokument ve formátu HTML. Dostupný na Internetu: http://jaja.kn.vutbr.cz/~belovic/IZP/8c_slozitost.pdf. Moore, S. The ISO 7185 Standard Pascal page [on-line]. 2009. [cit. 12. 5. 2012]. Dokument ve formátu HTML. Dostupný na Internetu: http://www.moorecad.com/standardpascal/. Němec, J. Preprocesor [on-line]. 2005. [cit. 25. 3. 2012]. Dokument ve formátu HTML. Dostupný na Internetu: http://www.linuxsoft.cz/article.php?id_article=611. Pecinovský, R. Jak hledat chyby v Programech [on-line]. 2008. [cit. 25. 4. 2012]. Dokument ve formátu HTML. Dostupný na Internetu: http://vyuka.pecinovsky.cz/debugging_z/chyby.html. Peterka, J. Linker [on-line]. 2010. [cit. 25. 4. 2012]. Dokument ve formátu HTML. Dostupný na Internetu: http://www.earchiv.cz/a95/a507c120.php3. Peterka, J. JIT [on-line]. 209. [cit. 21. 4. 2012]. Dokument ve formátu HTML. Dostupný na Internetu: http://www.earchiv.cz/axxxk160/a706k161.php3. Rohovský, T. Céčko – Historie a vlastnosti [on-line]. 2008. [cit. 14. 3. 2012]. Dokument ve formátu HTML. Dostupný na Internetu: http://www.jazykc.ic.cz/vyuka/historie.html. Rybička, J. Úvod do teorie formálních jazyků Konvoj, 1999. 39 s. ISBN 80-85615-25-8.
9
LITERATURA
63
Serafini, T. Compilers benchmark [on-line]. 2002. [cit. 25. 4. 2012]. Dokument ve formátu HTML. Dostupný na Internetu: http://www.simulanalog.org/compiler.htm. Skoupil, D. Úvod do paradigmat programován [on-line]. 1994. [cit. 25. 4. 2012]. Dokument ve formátu HTML. Dostupný na Internetu: http://www.hluchak.cz/~krhanek/files/paradigmata.pdf. Vavrečková, Š. Programování překladačů Ediční středisko FPF SU Opava, 2008. 218 s. ISBN 978-80-7248-493-5. . Ventruba, M. Schopnosti překladačů vybraných objektově orientovaných jazyků [on-line]. 2011. [cit. 15. 3. 2012]. Dokument ve formátu HTML. Dostupný na Internetu: https://is.mendelu.cz/auth/lide/ clovek.pl?zalozka=7;id=21995;studium=41819;download_prace=1. Vondrák, I. Úvod do softwarového inženýrství [on-line]. 2002. [cit. 25. 4. 2012]. Dokument ve formátu HTML. Dostupný na Internetu: http://vondrak.cs.vsb.cz/download/ Uvod_do_softwaroveho_inzenyrstvi.pdf. Wikipedia.org: Vývojová prostředí [on-line]. 2012. [cit. 15. 4. 2012]. Dokument ve formátu HTML. Dostupný na Internetu: http://cs.wikipedia.org/wiki/ V%C3%BDvojov%C3%A9_prost%C5%99ed%C3%AD. Willus.com: Win32 Compiler Benchmarks [on-line]. 2011. [cit. 12. 5. 2012]. Dokument ve formátu HTML. Dostupný na Internetu: http://www.willus.com/ccomp_benchmark.shtml?p1.