Překlad do strojového kódu
C++ 11

image_printTisk

V tomto článku se seznámíme s tím, jak překladač převádí zdrojový kód programu do binární podoby spustitelné operačním systémem. Článek se zmiňuje nejen o procesu překladu zdrojových kódů, ale i o jejich organizaci do souborů a dále si něco povíme o přenositelnosti programů v C++ mezi platformami, ať jí je myšlen jiný operační systém nebo implementace překladače.

Začněme organizací zdrojových kódů do souborů. Programy v C++ bývají rozděleny do samostatných modulů, které se překládají izolovaně a nezávisle na modulech ostatních. Každý takový modul je tvořen jedním souborem s příponou .CPP, který obsahuje jeho vlastní implementaci. Vazby mezi vlastními moduly a sdílení jejich dat se řeší pomocí tzv. hlavičkových souborů, mající zpravidla příponu .H. Tyto hlavičkové soubory se pak vkládají při překladu do CPP souborů pomocí direktivy #include. Jedno takové použití této direktivy jsme už potkali v úvodním článku První program v C++, kde se importovali prostředky pro práci s textovou konzolí.

Ukažme si ale schematicky na diagramu, jak například mohou vazby mezi CPP soubory a hlavičkovými soubory vypadat.

Na diagramu jsou vidět tři moduly reprezentované soubory MoveGen.cpp, ChessBoard.cpp a Engine.cpp. Každý z těchto souborů importuje svůj příslušný hlavičkový soubor, který musí obsahovat deklarace a jiné jazykové prvky, které příslušný modul dává k dispozici navenek modulům ostatním. Na diagramu je tato vazba naznačena černou šipkou. Nakonec šipkou červenou je naznačen import funkcionality z jiných modulů. Tento import naznačuje, že moduly Engine a MoveGen využívají služeb  modulu ChessBoard a modul ChessBoard využívá zase funkcionality modulu MoveGen, jak naznačuje diagram.

Nyní se již ale zabývejme procesem vlastního překladu zdrojových kódů do kódu strojového. Všimněme si následujícího diagramu, na kterém je zobrazeno schema procesu překladu.

 

 

 

 

 

 

 

 

Schema ukazuje v zelených elipsách tři moduly. Ty jsou překladačem, samostatně a nezávisle na sobě, přeloženy do tzv. objektových souborů, na diagramu naznačených elipsou modrou. Výsledné objektové soubory mají zpravidla přípony .OBJ nebo .O, v závislosti na volbě překladače. Tyto soubory již obsahují vlastní spustitelný kód, ale zatím to není ještě výsledný program, neboť chybí navázání vazeb mezi moduly, jejichž vazby, jak již bylo uvedeno, se zprostředkovávají sdílením hlavičkových souborů.

Spojení objektových modulů pak zastává druhá fáze překladu pomocí linkeru. Tento program vezme na vstup seznam modulů a spojí všechny odkazy a vazby na moduly jiné, čímž je dokončen překlad výsledného programu. Další důležitou věcí, kterou nesmíme opomenout je, že linker nemusí konstruovat vazby jen mezi objektovými soubory překládaného programu, ale často se připojují ke spojování i různé statické knihovny třetích stran. Tyto staticky linkované knihovny mají zpravidla přípony .LIB nebo .A a jsou výsledkem sestavovacího procesu linkerem z nějakého dřívějšího překladu.

Výsledkem překladu zdrojových kódů mohou být v podstatě tři různé produkty:

  • Vlastní spustitelný program.
  • Dynamická knihovna, která je připojována operačním systémem k programu až při jeho spuštění.
  • Statická knihovna, která se stává pevnou součástí spustitelné podoby programu procesem linkování.

O jazyku C++ bývá rozšířen mýtus, že není přenositelný na různé platformy. Je to pravda jen z části v pohledu, že samozřejmě výsledný strojový kód je vázaný na konkrétní platformu. Dále je samozřejmě pravdou, že jazyk C++ nedisponuje žádným bytecodem jako Java nebo CIL jazykem jako technologie .NET. U jazyka C++ se jeho přenositelnosti dosahuje přes jeho zdrojové kódy, které jsou překládány pro každou platformu zvlášť, kdy musí být při psaní daného programu dodrženy prvky standardu jazyka C++ a využívání standardní knihovny C++, funkcí STL knihovny, případně různých dalších knihoven jako Boost nebo Qt, které poskytují různé úrovně abstrakce od konkrétní platformy.

Tak jako nic není zcela ideální, tak samozřejmě mohou nastat potíže i v případě přenositelnosti zdrojových kódů C++.  Potíže mohou nastat nejen při překladu na různé operační systémy jako Windows, Linux či MacOS, ale velkou roli hraje i volba překladače, který je použit. Napřed si musíme ujasnit, zda potřebujeme vůbec psát přenositelný kód nebo nám stačí cílit pouze na jednu či několik platforem. Vše samozřejmě závisí na účelu psaného software. Při použití standardní knihovny STL, případně nadstavbových knihoven jako Boost či Qt můžeme výsledný zdrojový kód téměř dokonale abstrahovat od konkrétní platformy. Potíže nastávají jen v některých specifických oblastech. Jmenujme například instrukce pro práci SSE pomocí vestavěných funkcí. Předchozí odkaz ukazuje na variantu těchto instrukcí pro G++, u jiných překladačů tomu bude jinak. Pokud používáme takovouto funkcionalitu nebo nějaká rozšíření implementace, která není součástí standardu, musíme daná specifika lokalizovat nejlépe do jednoho konkrétního souboru a rozlišit mezi jednotlivými platformami a překladači metodou podmíněného překladu za pomocí maker.

Shrnutí:

  • Zdrojový kód C++ bývá rozdělen do samostatných modulů, které jsou překládány nezávisle na sobě.
  • Soubory CPP obsahují implementaci a hlavičkové soubory slouží ke sdílení jazykových prvků mezi moduly.
  • Hlavičkové soubory se vkládají pomocí direktivy procesoru #include.
  • Překlad zdrojových kódů má dvě fáze, první je tvorba objektových souborů z CPP souborů, po té následuje jejich linkovací proces a finální sestavení binární podoby programu.
  • Výsledkem sestavení může být spustitelný program, dynamická nebo statická knihovna.
  • Programy v C++ nejsou přenositelné v jejich binární podobě, lze je ale přeložit do binární podoby na různé platformy, samozřejmě při dodržení příslušných konvencí a použití knihoven pro abstrakci od konkrétní platformy.

 

image_printTisk
Překlad do strojového kódu
C++ 11
4.1 (82.86%) 7 hlasů

Související články

  • První program v C++ Při vysvětlování jazyka C++ začneme tím nejklasičtějším příkladem, a to je varianta programu "Ahoj, světe". Vysvětlíme si primárně důležitost funkce jménem main, jejíž význam bude na první […]
  • Komentáře Tento článek pojednává o způsobu zápisu komentářů ve zdrojových kódech jazyka C++. Budou popsány oba druhy komentářů, tedy jednořádkové i jejich víceřádková varianta. Použití […]
  • Obsluha chyb pomocí výjimek Tento článek je článkem úvodním tematice obsluhy chyb v jazyce C++. V tomto článku si představíme motivaci zavedení výjimek jazyka C++ jako aparátu pro detekci a zpracování chyb. Dále […]
  • Organizace dat v paměti RAM Tento článek poskytuje teoretický úvod do způsobu uspořádání paměti aplikace. Seznámíme se s jednotlivými bloky paměti a jejich významem a dále bude výklad stručně doplněn o téma […]
  • Práce se soubory pomocí knihovny STL V tomto článku si popíšeme základy práce se soubory pomocí knihovny STL. Práce se soubory pomocí této knihovny je mnohem snadnější, než pomocí staršího přístupu pomocí standardní knihovny […]
  • Číselné datové typy V této kapitole se objasníme pojem, co je to datový typ. Dále si ukážeme základní číselné datové typy, se kterými jazyk C++ operuje a předvedeme si různé varianty zápisu čísel, hlavně […]