Preklad programu

[  Základní pojmy   Prekladac GCC  |  Preklad s knihovnou <math.h>  |  Preklad programu  |  Prepínace kontrolující výstup  |  Volba dialektu jazyka C/C++  |  Informace pro debugger, optimalizace  |  Varování, chyby  ]

Základní pojmy

Protoze predpokládám, ze nekterí ctenári s nástroji pro preklad programu nikdy nepracovali, musíme si vysvetlit pár základních pojmu. Pokud tyto pojmy znáte, muzete je preskocit a pokracovat cástí o pouzití prekladace GCC.

Prekladac, kompilátor, anglicky compiler
je program, který vezme zdrojový text programu a prelozí jej do jazyka stroje, coz jsou obvykle kódy instrukcí pro daný procesor. Výsledkem tohoto prekladu obvykle není spustitelný program, protoze v místech kde se volají podprogramy z jiných modulu a knihoven, nejsou konkrétní adresy techto podprogramu, ale pouze znacky, které se zpracují pozdeji pri linkování. Souborum, které produkuje prekladac se ríká objektové soubory (nemá to nic spolecného s objektove orientovaným programováním). Dulezitou funkcí prekladace je syntaktická kontrola.
Sestavovací program, linker
slouzí k sestavení samostatne prelozených modulu a knihoven do funkcního celku. Linker do kódu doplní konkrétní adresy podprogramu (statický preklad) nebo kód pro jejich zavolání (pri pouzití dynamických knihoven). Pokud vytváríme spustitelný program (u knihoven to je trochu jinak), linker nakonec doplní do programu kód, který se pouzívá pri spustení programu. Tato cást, stejne jako formát pouzitých statických nebo dynamických knihoven se lisí v závislosti na pouzitém operacním systému a hardwarové platforme. Pokud proto chceme vyrobit spustitelný program pro jinou platformu, musíme u jazyku typu C, C++ provést preklad na zvolené platforme znovu.
Debugger
je program pro ladení a hledání chyb v programu. Aby melo ladení s debuggerem smysl, je obvykle nutné ríci prekladaci, aby do výsledného kódu pridal speciální znacky, díky nimz si debugger bude umet spojit konkrétní cást binárního kódu programu s konkrétními rádky zdrojového textu.
Preprocessor
je speciální program pouzívaný v jazycích C a C++ pro zpracovávání maker a symbolických konstant. Tento program v podstate provádí pouze textové náhrady definovaných symbolu v textu a umoznuje podmínený preklad. Príkazy pro preprocessor zacínají vzdy znakem mrízky (#), napríklad #define nebo #ifndef. Príkazy preprocessoru byste, alespon zpocátku, meli pouzívat co nejméne.
Assembler
je program pro preklad jazyka symbolických instrukcí do binárního kódu. Nekdy bývá nesprávne zamenován se samotným jazykem symbolických instrukcí, coz je vemi nízkoúrovnový jazyk, kde zdrojový kód tvorí posloupnost zkratek instrukcí procesoru. Pri velmi speciálních prílezitostech lze jazyk symbolických instrukcí kombinovat s kódem v jazyce C. Velmi speciální situace zahrnují prístup k nejnizsím úrovním hardwaru a brutální optimalizace. Pri bezném programování se s tím nesetkáte (a ani by to vetsinou nebylo prospesné).
Syntaktická chyba
je prohresek proti gramatice programovacího jazyka. Pocítac je matematický stroj a vyzaduje naprosto jednoznacný predpis své cinnosti. Ve zdrojovém kódu nesmí být zádné syntaktické chyby, aby bylo jednoznacné, co má prekladac delat. Prekladac neví, co chcete naprogramovat, proto se nemuze ani pokouset o opravu vasich chyb, to musíte udelat sami. Mezi syntaktické chyby patrí predevsím preklepy, ale muze to být také pouzití nekompatibilních datových typu nebo treba chybné pouzití operátoru (napr. nemuzete zkouset násobit textové retezce).
Sémantická chyba
je chyba v logice vaseho programu. Vás program muze být syntakticky správný, prekladac jej prelozí, linker slinkuje, ale program presto muze fungovat chybne. Za tyto chyby je vzdy zodpovedný programátor a je na nem, aby se jich zbavil. Tyto chyby prekladac ani linker neodhalí. Pokud máte stestí, muze na ne prekladac neprímo upozornit pomocí varovných hlásení pri prekladu.
Chybové hlásení
je zpráva, kterou vám prekladac nebo linker sdelují, proc nelze z vaseho kódu vytvorit spustitelný program. Tato zpráva obvykle obsahuje jméno souboru a císlo rádku, kde se chyba nachází. Pozor! V jazyce C muze nekdy prekladac odhalit chybu na jiném rádku, nez je skutecná prícina. Pokud se vám oznacené císlo rádku nezdá, zkuste hledat chybu i nekolik rádku okolo. Abyste mohli co nejlépe lokalizovat své chyby, piste na kazdý rádek zdrojového textu maximálne jeden príkaz. Usnadníte si tím nejen lokalizaci chyb, ale i ladení. Chybové hlásení obsahuje také vysvetlení, co je podle prekladace spatne.
Varovné hlásení
je upozornení, kterým vám prekladac nebo linker dávají najevo, ze vás program sice mozná jde prelozit, ale ze obsahuje podezrelé konstrukce, které mohou naznacovat závaznejsí problém. Moudrý programátor venuje varovným hlásením prekladace nálezitou pozornost. Vasí ambicí by mel být preklad bez varovných hlásení. Dobré porozumení chybovým hlásením vyzaduje znalost anglictiny a predevsím dobrou znalost fungování pocítace a logiky programovacího jazyka. Pokud zatím tyto znalosti nemáte, nezoufejte. Není tak tezké se to naucit. Cím více budete programovat, tím to pro vás bude snazsí.

Prekladac GCC

GCC znamená GNU Compiler Collection. Jak název napovídá, jde o kolekci programu urcených pro preklad programu napsaných v ruzných jazycích. V soucasné verzi (3.4) je podporováno nekolik programovacích jazyku (C, C++, Objective C, assembler, Ada, Java, Fortran77). Primárne je vsak tento prekladac urcen pro preklad jazyku C, C++ a Assembleru. Tento prekladac funguje v soucasné dobe na vetsine hlavních platforem (Unix, Windows, MacOS; Intel, PPC, Sparc, ruzné jednocipy, a jiné).

Nejdulezitejsími programy jsou prekladac, preprocesor, assembler a sestavovací program (linker). Clovek vsak nastestí nemusí znát konkrétní jména techto programu. Stací volat pouze prekladac (gcc pro jazyk C, g++ pro jazyk C++) a ten potom podle pouzitých parametru zavolá ty správné programy ve správném poradí.

Preklad programu

Predpokládejme, ze jste napsali klasický program Hello world a ulozili jej do souboru helloworld.c

#include <stdio.h>

int main(void)
{
  printf("Te péro sombréro!\n");
  return 0;
}

Z príkazové rádky tento soubor prelozíme následujícím príkazem:

$ gcc helloworld.c

Prekladac vytvorí spustitelný soubor a.out, který po spustení vypíse text:

$ ./a.out
Te péro sombréro!
$

Pri tomto zpusobu prekladu jsme ponechali implicitní nastavení prekladace. Není ovsem dobré spoléhat na standardní nastavení. Prekladac v tomto stavu nehlídá vsechny chyby, které by se v programu mohly vyskytnout. Zvláste zacátecníci by meli prekládat programy s ponekud prísnejsím nastavením. Prekladac potom bude vypisovat více varovných zpráv. Muze se to sice zdát otravné, ale uvazte, ze cím více chyb odhalí prekladac uz pri prekladu, tím více práce to usetrí pri ladení.

$ gcc -std=c99 -Wall -pedantic -g helloworld.c -o hello

S tímto nastavením se budou prekládat vsechny projekty predmetu IZP. Pokud chcete prekládat s jeste prísnejsím nastavením, zkuste toto:

$ gcc -std=c99 -Wall -Werror -pedantic-errors -g helloworld.c -o hello

V prostredí Windows se prekladac pouzívá stejným zpusobem. Rozdíl je v tom, ze prostredí Windows není case-sensitive, takze je jedno, jestli soubory pojmenováváme velkými nebo malými písmeny. Aby byly programy prenositelné, je dobré si zvyknout pojmenovávat je výhradne malými písmeny. Vyhnete se tím prípadným problémum pri prenosu programu do prostredí Linuxu.

Preklad s knihovnou <math.h>

Pri prekladu programu, který pouzívá matematické funkce z math.h je nutné pri prekladu pridat prepínac -lm, který zajistí prilinkování matematické knihovny. Bez této knihovny sice pujde program prelozit, ale nepujde jej slinkovat.

$ gcc -std=c99 -Wall -pedantic -g -lm matematika.c -o matematika

Pouzívání knihoven je podrobneji probíráno v kapitole Moduly a knihovny.

$ gcc -std=c99 -Wall -pedantic -g -lm matematika.c -o matematika

Prepínace kontrolující výstup

Parametr Význam Poznámka
-c Pouze zkompiluje zdrojový soubor, ale neprovede linkování. Tento prepínac se pouzívá pri oddeleném prekladu více zdrojových souboru. Je mozné jej pouzít pro syntaktickou kontrolu zdrojového souboru - je to pak rychlejsí, protoze se neprovádí kompilace, prekladac pouze vypíse chyby a varovné zprávy.
-o soubor Ulozí výstup do spustitelného souboru daného jména. Bez tohoto prepínace prekladac vytvárí soubor, který se jmenuje a.out (Linux) nebo a.exe (Windows).  
-E Preklad se zastaví po zavolání preprocesoru. Toto je uzitecné, kdyz se chcete podívat, zda se správne rozgenerovala makra.  
-S Preklad se zastaví po vygenerování kódu pro assembler. Toto pouzívají zvrhlíci, které baví rochnit se ve zmeti instrukcí. Obcas je mozné rucne zmenit pár instrukcí v rámci optimalizací, ale vetsinou assemblerový kód vyuzijete tehdy, kdyz chcete pred nekým delat machra. ;-) Pozor! Pokud se vám pomocí tohoto povede sbalit zivotní partnerku, vystavujete se nebezpecí, ze vase deti budou mít ve skole prezdívky jako sprt, integrál nebo EAX!
-v Vypíse parametry, se kterými byl prekladac sám prelozen, plus jeho verzi. Z techto údaju se dají vycíst zajímavé údaje, jako kde prekladac ocekává statické, ci dynamické knihovny, nebo jestli zvládá vícevláknové aplikace. Podobnou funkci má i prepínac -###. Podrobnosti viz manuálovou stránku gcc.
--version Vypíse verzi prekladace.  

Volba dialektu jazyka C/C++

Prepínac Popis Poznámka
-std=c99 Zapíná specifikaci jazyka C podle normy ISO z roku 1999. Tento prepínac rozhodne pouzívejte! Zajistíte tím, ze program bude prenositelný mezi moderními prekladaci na mnozství platforem a vyhnete se nechtenému pouzití nestandardních rozsírení prekladace GCC.
-std=c++98 Zapíná specifikaci jazyka C++ podle normy ISO z roku 1998. Pouze pro jazyk C++. Nepouzívat u Céckových programu!
-ansi Zapíná specifikaci jazyka C podle normy ANSI. Tento prepínac je ekvivalentní prepínaci -std=c89. Radeji pouzívejte -std=c99. Tento prepínac je pouzitelný, kdyz chceme, aby byl program kompatibilní se starsí verzí prekladace.

Informace pro debugger, optimalizace

Parametr Význam Poznámka
-g, -g1, -g2, -g3 Prekladac bude do výsledného kódu pridávat pomocné ladící informace pro debugger. Pokud pri prekladu není zvolen nejaký z techto prepínacu, bude debugger schopen zobrazovat pouze informace na úrovni assembleru - nebude schopen zobrazovat názvy funkcí a promenných. Císlo za prepínacem udává, jak podrobné ladící informace se budou generovat. Prepínac -g je ekvivalentní prepínaci -g2. Tyto prepínace lze pouzít zároven s prepínacem -O, ale vetsinou to nemá smysl. U starsích verzí prekladace to muze pusobit potíze.
-ggdb, -ggdb1,
-ggdb2, -ggdb3
Podobné jako u prepínace -g, ale ladící informace budou optimalizovány pro debugger gdbg. Existují i jiné prepínace, kterými se dá zapnout optimalizace pro jiné debuggery, ale gdb je nejbeznejsí. Více viz manuálovou stránku gcc.
-O, -O1, -O2, -O3 Zapne optimalizaci výsledného kódu. Císlo za prepínacem specifikuje úroven optimalizace. Prepínace -O a -O1 jsou ekvivalentní. Cím vyssí úroven optimalizace zvolíte, tím delsí dobu bude trvat preklad. Zvláste na pomalých strojích je vhodné zapínat optimalizace pouze pri konecné kompilaci, ne pri bezném psaní kódu. (Platí pro jednoduché projekty.) Tento prepínac pouzívejte spolecne s prepínacem -g jenom kdyz víte co deláte.
-Os Zapne optimalizaci kódu zamerenou na velikost výsledného souboru. V podstate zapne vsechny optimalizace -O2, které nemají za následek zvetsení výsledného kódu, plus pridá nekteré dalsí optimalizace. Pouzívá se výjimecne
-O0 Vypne optimalizace. Tento prepínac je implicitne zapnut.  
-p, -pg Prekladac bude do výsledného kódu pridávat informace pouzitelné pro profilovací analýzu programem prof nebo gprof (pro -pg). Profilování je statistická analýza behu programu, ze které se dá zjistit, ve které funkci program tráví nejvíce casu. Pokud vás svrbí prsty a rádi byste svuj program optimalizovali, nejprve provedte profilovací analýzu. Optimalizovat funkci, která se vyvolá dvakrát behem celého behu programu, je mrhání vasím casem. Tento parametr je nutné pouzít i pri linkování.

Varování, chyby

Parametr Význam Poznámka
-Wall Zapíná produkci varovných zpráv pro témer vsechny aspekty, které prekladac umoznuje hlídat. Existuje velké mnozství parametru -W..., které dovolují urcovat konkrétní aspekty jazyka, které má prekladac hlídat. Existují aspekty, které se pomocí -Wall nezapnou, ale ty se týkají výhradne jazyka C++. Velmi dulezité pokud se chceme vyhnout mnozství nepríjemných chyb.
-pedantic Hlídá, jestli program striktne dodrzuje normu ISO C nebo ISO C++ zadanou parametrem -std. Pokud program normu nedodrzuje, vypisuje se varování. Velmi dulezité pro psaní prenositelných programu.
-Wextra, -W Produkuje nekterá dalsí uzitecná varování. Zapnutím tohoto prepínace prinutíme prekladac, aby provádel (cástecnou) sémantickou kontrolu kódu.
Prepínac -W je zastaralý. Nový název prepínace -Wextra je výstiznejsí a nehrozí jeho zámena s prepínacem -w.
 
-w Potlací veskeré varovné zprávy. Pozor! Má naprosto jinou funkci nez prepínac -W (velké písmeno), snadno se s ním plete a muze zpusobovat falesný pocit, ze prekládaný program je v naprostém porádku.
-Werror Vsechna varování interpretuje jako chyby. Pro zacátecníky je velmi uzitecné mít jej zapnutý.
-pedantic-errors Jako -pedantic, ale místo varování produkuje rovnou chyby. Pro zacátecníky je velmi uzitecné mít jej zapnutý.
Zdá se, ze nekteré implementace GCC pod Windows pouzívají v hlavickových souborech nestandardní rozsírení, takze tento prepínac zde nejde pouzít.

Autor: David Martinek. Poslední modifikace: 9. ríjna 2011. Pokud v tomto dokumentu narazíte na chybu, dejte mi prosím vedet.