V tomto Φlßnku se podφvßme na sedm p°ekladaΦ∙ jazyka C++, s nimi₧ se m∙₧eme dnes setkat, a pokusφme se porovnat je z r∙zn²ch hledisek.
P╪EKLADA╚E
PorovnßvanΘ p°ekladaΦe uvßdφme v abecednφm po°adφ.
Borland C++ Builder 6 (BC6). Byl uveden na trh na poΦßtku roku 2002 jako souΦßst stejnojmennΘho v²vojovΘho nßstroje firmy Borland. K porovnßnφ jsme pou₧ili provedenφ Enterprise.
Borland C++BuilderX (BCX). Objevil se ve druhΘ polovin∞ roku 2003 a je takΘ souΦßstφ stejnojmennΘho v²vojovΘho nßstroje firmy Borland. I tentokrßt jsme k porovnßnφ pou₧ili provedenφ Enterprise.
Borland C++BuilderX - Technology Preview (BCXP). Je souΦßstφ nßstroje Borland C++BuilderX a lze jej instalovat samostatn∞. Jde v podstat∞ o beta verzi p°ekladaΦe, kter² bude souΦßstφ p°φÜtφ verze tohoto nßstroje.
GNU mingw32 (GNU). Jde o freewarov² p°ekladaΦ g++, verzi 3.2, tj. o p°ekladaΦ GNU C++ pro dvaat°icetibitovß Windows, konfigurovan² jako mingw. Lze jej zφskat z webov²ch strßnek GNU nebo nap°φklad spolu s nßstrojem Borland C++BuilderX.
Intel C++ 7.1 (INT71). Tento p°ekladaΦ je souΦßstφ sady v²vojov²ch nßstroj∙ firmy Intel z roku 2003. Nelze ho vÜak pou₧φvat samostatn∞, vy₧aduje instalaci Microsoft Platform SDK. Vyu₧φvß hlaviΦkovΘ soubory a linker p°ekladaΦ∙ firmy Microsoft. Pokud je k dispozici MS Visual C++ .NET 2002 nebo 2003, integruje se do jeho IDE jako implicitnφ p°ekladaΦ. P°ekladaΦ INT71 existuje ve dvaat°icetibitovΘm a Φty°iaÜedesßtibitovΘm provedenφ; zde jsme se zab²vali pouze verzφ dvaat°icetibitovou.
Microsoft Visual C++ .NET v. 2002 (VC02). Tento p°ekladaΦ je souΦßstφ Microsoft Visual Studia .NET 2002 a umo₧≥uje p°eklad pro Win32 a pro platformu .NET. Proto₧e ostatnφ p°ekladaΦe neumo₧≥ujφ p°eklßdat programy pro .NET, budeme se tφmto p°ekladaΦem zab²vat pouze z hlediska p°ekladu program∙ pro platformu Win32.
Microsoft Visual C++ .NET v. 2003 (VC03). Novß verze Visual C++ byla uvedena na trh v polovin∞ roku 2003. I o nφ budeme hovo°it pouze z hlediska p°ekladu program∙ pro platformu Win32.
O CO N┴M JDE
P°ekladaΦe jazyka C++ lze srovnßvat z °ady r∙zn²ch hledisek. V tomto Φlßnku se zam∞°φme na nßsledujφcφ kritΘria:
shoda implementovanΘho jazyka C se standardem ISO/IEC 9899:1999,
shoda implementovanΘho jazyka C++ se standardem ISO/IEC 14882:1998,
rychlost p°elo₧en²ch program∙ (tedy kvalita optimalizace).
I kdy₧ na prvnφ pohled nejzajφmav∞jÜφ je asi porovnßnφ p°ekladaΦ∙ z hlediska efektivity p°elo₧enΘho k≤du, zaΦneme od shody p°ekladaΦ∙ se standardy, nebo¥ ta ovliv≥uje p°enositelnost program∙ mezi p°ekladaΦi a platformami, a to takΘ nenφ zanedbatelnΘ.
JAZYK C
Nedφlnou souΦßstφ vÜech porovnßvan²ch p°ekladaΦ∙ jazyka C++ je i p°ekladaΦ jazyka C. Pro vÜechny porovnßvanΘ produkty platφ, ₧e jako program v jazyce C se implicitn∞ p°eklßdß zdrojov² soubor, kter² mß p°φponu .c.
Prvnφ mezinßrodnφ standard jazyka C, tedy ISO/IEC 9899:1990, byl p°ijat v r. 1990, tak₧e na konci devadesßt²ch let jej implementovaly ji₧ vÜechny b∞₧n∞ dostupnΘ p°ekladaΦe. VÜechny porovnßvanΘ p°ekladaΦe krom∞ GNU takΘ implementujφ tzv. strukturovanΘ v²jimky (structured exception handling) a n∞kterß dalÜφ microsoftskß rozÜφ°enφ jazyka C pro Win32.
V roce 1999 vÜak byla p°ijata novß verze standardu, kterß p°inesla °adu ·prav a rozÜφ°enφ. Ze zm∞n, kterΘ novß verze normy jazyka C p°inesla, jsme pro ·Φely naÜeho porovnßnφ vybrali tyto rysy jazyka C:
restringovanΘ ukazatele (modifikßtor restrict),
inicializaci jen vybran²ch slo₧ek polφ a struktur,
vestav∞nß komplexnφ Φφsla, podporu typ∙ long long a unsigned long long,
nekonstantnφ hornφ mez v deklaraci lokßlnφho pole, deklaraci zapisovanou mezi p°φkazy,
literßly typu pole a struktura,
funkci s modifikßtorem inline, hlaviΦkov² soubor <stdint.h>,
p°inßÜejφcφ alternativnφ p°φstup k implementovan²m celoΦφseln²m typ∙m.
Podrobn∞jÜφ porovnßnφ, je₧ zahrnuje v∞tÜφ poΦet nov∞ po₧adovan²ch rys∙, najdete spolu se struΦn²mi poznßmkami o v²znamu uveden²ch konstrukcφ v rozÜφ°enΘ verzi tohoto Φlßnku na Chip CD, kter² je p°φlohou tohoto Φφsla.
V▌SLEDKY
Podφvejme se nynφ, jak jednotlivΘ p°ekladaΦe z tohoto hlediska dopadly. ZaΦneme od v∞cφ, kterΘ v∞tÜina p°ekladaΦ∙ pomφjφ:
Modifikßtor restrict v deklaraci ukazatele a inicializaci pouze vybran²ch slo₧ek polφ nebo struktur podporuje pouze p°ekladaΦ BCXP a INT71.
Komplexnφ Φφsla podle novΘho standardu (datovΘ typy float _Complex atd.) implementuje pouze p°ekladaΦ BCXP. V omezenΘm rozsahu ho implementujφ takΘ GNU a INT71. Ty sice dovolujφ datovΘ typy pro komplexnφ Φφsla pou₧φt a provßd∞t s nimi b∞₧nΘ aritmetickΘ operace, neobsahujφ vÜak hlaviΦkov² soubor <complex.h> s deklaracemi pomocn²ch maker, jako je I, p°edstavujφcφ imaginßrnφ jednotku, a dalÜφ.
Pokud jde o celoΦφselnΘ typy long long a unsigned long long, je situace pon∞kud zmatenß. VÜechny p°ekladaΦe dovolujφ deklarovat prom∞nnΘ t∞chto typ∙ a zapisovat v programu literßly t∞chto typ∙. Ve vÜech p°φpadech jde o ekvivalent typ∙ __int64 a unsigned __int64 z prost°edφ Win32. Äßdn² z p°ekladaΦ∙ vÜak nepodporuje standardem po₧adovanou specifikaci "%lld" (resp. "%llu") pro v²stup t∞chto Φφsel realizovan² pomocφ funkcφ z rodiny printf(). Ve vÜech p°ekladaΦφch je t°eba pou₧φt specifikaci "%I64d", resp. "%I64u".
Mo₧nost specifikovat hornφ mez pole pomocφ nekonstantnφho v²razu, mo₧nost zapisovat deklarace kdekoli mezi v²razy a mo₧nost pou₧φvat literßly, je₧ p°edstavujφ pole nebo struktury, poskytujφ pouze p°ekladaΦe BCXP, GNU a INT71.
Ji₧ po n∞kolik let se v p°ekladaΦφch jazyka C objevuje jako rozÜφ°enφ mo₧nost v deklaraci funkce pou₧φt modifikßtor __inline, kter² m∙₧e vΘst k rychleji b∞₧φcφmu p°elo₧enΘmu programu. SouΦasn² standard ovÜem po₧aduje klφΦovΘ slovo inline (bez ·vodnφch podtr₧φtek). Tomuto po₧adavku vyhovujφ pouze p°ekladaΦe BCXP, GNU a INT71, v ostatnφch musφme pou₧φt __inline.
HlaviΦkov² soubor <stdint.h> m∙₧eme pou₧φvat v p°ekladaΦφch BC6, BCX, BCXP a GNU; p°ekladaΦe MSVC02, MSVC03 a INT71 ho neposkytujφ. (P°ipome≥me si vÜak, ₧e p°ekladaΦ Intel vyu₧φvß hlaviΦkovΘ soubory z MS Visual C++.)
P°ehledn∞ tyto v²sledky shrnuje tabulka 1.
V p°ekladaΦφch BCXP a INT71 je t°eba povolit podporu novΘho standardu jazyka C zvlßÜtnφm p°epφnaΦem. Shrnuto jazykem politik∙, je z°ejmΘ, ₧e implementace nov²ch rys∙ jazyka C nep°edstavuje pro tv∙rce p°ekladaΦ∙ C++ prioritu.
JAZYK C++
Zde je situace p°ece jen veselejÜφ. Nßstroje, kterΘ vyu₧φvajφ b∞₧nφ programßto°i, jsou v p°evß₧nΘ v∞tÜin∞ ji₧ stabilnφ souΦßstφ dodßvan²ch p°ekladaΦ∙ a odchylky od standardu se t²kajφ hlavn∞ rys∙ tohoto jazyka, kterΘ ocenφ p°edevÜφm auto°i knihoven. (Existujφ vÜak i v²jimky z tohoto pravidla.) To se t²kß p°edevÜφm Üablon: Jejich zßkladnφ vlastnosti jsou implementovßny vÜemi porovnßvan²mi p°ekladaΦi. Na odchylky od standardu lze vÜak narazit v n∞kter²ch pro b∞₧nΘho programßtora spφÜe okrajov²ch oblastech, jako je nap°. parcißlnφ specializace Üablon.
Pro porovnßnφ uveden²ch p°ekladaΦ∙ jsme vybrali nßsledujφcφ rysy jazyka C++:
Koenigovo vyhledßvßnφ (vyhledßvßnφ p°etφ₧en²ch funkcφ v prostorech jmen parametr∙),
specifikace typ∙ v²jimek, kterΘ se mohou z funkce rozÜφ°it,
exportnφ Üablony,
vno°enΘ Üablony,
parcißlnφ specializace Üablon objektov²ch typ∙,
parcißlnφ °azenφ Üablon obyΦejn²ch funkcφ.
V▌SLEDKY
ZaΦneme op∞t od vlastnostφ, kterΘ p°ekladaΦe nejvφce opomφjejφ:
O implementaci klφΦovΘho slova export, tedy tzv. exportnφch Üablon, se pokusil pouze jedin² z uveden²ch p°ekladaΦ∙, a to BCXP. K tomu je vÜak t°eba poznamenat, ₧e °ada Φlen∙ standardizaΦnφ komise se netajφ nßzorem, ₧e tento rys by m∞l b²t z jazyka odstran∞n.
Mo₧nost specifikovat typy v²jimek, kterΘ se mohou z danΘ funkce nebo metody rozÜφ°it, pomocφ klφΦovΘho slova throw za hlaviΦkou funkce byla souΦßstφ jazyka C++ u₧ v dobßch dßvno p°ed p°ijetφm standardu. P°esto se kupodivu najdou p°ekladaΦe, kterΘ tuto mo₧nost dodnes neimplementujφ, nebo ji implementujφ jen omezen∞. P°ekladaΦe INT71, MSVC02 a MSVC03 sice dovolujφ tuto specifikaci k funkci p°ipojit, ale ignorujφ ji. Ostatnφ porovnßvanΘ p°ekladaΦe ji implementujφ v plnΘm rozsahu.
I kdy₧ vyhledßvßnφ jmen p°etφ₧en²ch funkcφ v prostorech jmen urΦen²ch operandy (Koenigovo vyhledßvßnφ) usnad≥uje p°edevÜφm pou₧φvßnφ p°etφ₧en²ch operßtor∙, platφ toto pravidlo i pro "obyΦejnΘ" funkce. AΦ jde na prvnφ pohled o neproblematickou zßle₧itost, p°ekladaΦe BCXP a MSVC02 provßd∞jφ implementaci pouze pro p°etφ₧enΘ operßtory.
P°ekladaΦ MSVC02 sice dovoluje definovat vno°enou Üablonu, po₧aduje vÜak, abychom do t∞la obklopujφcφ t°φdy zapsali celou jejφ definici, nikoli pouze deklaraci. (Jin²mi slovy, vno°enß Üablona musφ b²t v MSVC02 deklarovßna in-line.) Ostatnφ porovnßvanΘ p°ekladaΦe dovolujφ deklarovat vno°enΘ Üablony uvnit° i vn∞ obklopujφcφ funkce.
P°ekladaΦ MSVC02 nepodporuje parcißlnφ specializaci Üablon objektov²ch typ∙ ani parcißlnφ °azenφ Üablon obyΦejn²ch funkcφ. Ostatnφ porovnßvanΘ p°ekladaΦe tyto mo₧nosti implementujφ.
P°ehled v²sledk∙ porovnßvßnφ p°ekladaΦ∙ z hlediska implementace jazyka C++ najdete v tabulce 2.
EFEKTIVITA P╪ELOÄEN╔HO K╙DU
Z tohoto porovnßvßnφ jsme vypustili p°ekladaΦ BCXP, nebo¥ jde v podstat∞ o beta verzi Technology Preview sice znφ vzneÜen∞ji, ale neznamenß nic jinΘho - a nenabφzφ mo₧nost optimalizace p°elo₧enΘho k≤du.
Pro porovnßnφ jsme zvolili n∞kolik testovacφch program∙, kterΘ ukazujφ r∙znΘ strßnky optimalizace - prßci s reßln²mi Φφsly, prßci s pam∞tφ, efektivitu vstupnφch a v²stupnφch operacφ apod. Pou₧ili jsme nßsledujφcφ programy:
╪eÜenφ problΘmu 13 dam. V tΘto ·loze jde o to, rozmφstit 13 dam na Üachovnici o rozm∞ru 13 x 13 polφ tak, aby se ₧ßdnΘ dv∞ navzßjem neohro₧ovaly. Program mß urΦit celkov² poΦet mo₧n²ch °eÜenφ, nevypisuje je. (Poznamenejme, ₧e tato ·loha mß p°es 70 000 °eÜenφ.)
P°eΦtenφ 30 000 reßln²ch Φφsel ze souboru a jejich v²pis na konzolu. AΦ by se mohlo zdßt, ₧e vstupnφ a v²stupnφ operace, provßd∞nΘ ve vÜech p°φpadech stejn²m operaΦnφm systΘmem, zaberou p°evß₧nou v∞tÜinu Φasu, nenφ tomu tak a v²sledky se pro jednotlivΘ p°ekladaΦe liÜφ. LiÜφ se pochopiteln∞ i v²sledky pro t²₧ p°ekladaΦ, a to podle toho, zda pou₧ijeme vstupnφ a v²stupnφ funkce z jazyka C (z hlaviΦkovΘho souboru <stdio.h>), nebo objektovΘ datovΘ proudy z jazyka C++ (z hlaviΦkovΘho souboru <iostream>).
Zapl≥ovßnφ a vyprazd≥ovßnφ spojovΘho seznamu. Tento program testuje rychlost prßce s pam∞tφ tak, ₧e opakovan∞ (10 000krßt) ulo₧φ do spojovΘho seznamu 1000 cel²ch Φφsel a pak tento seznam vyprßzdnφ.
Pro test v²poΦt∙ s reßln²mi Φφsly jsem pou₧il program, kter² °eÜφ jistou zvlßÜtnφ soustavu 40 lineßrnφch algebraick²ch rovnic o 40 neznßm²ch.
Efektivitu implementace oÜet°ovßnφ v²jimek jsem testoval na opakovanΘm volßnφ funkce, kterß v₧dy vyvolß v²jimku. Testovacφ program ji volß 100 000krßt. (Tomuto kritΘriu vÜak nenφ t°eba p°iklßdat p°φliÜ velkou vßhu - koneckonc∙, v²jimky by m∞ly b²t v programech v²jimeΦnΘ. Na druhΘ stran∞ ho vÜak nelze zcela pominout.)
Dobu pot°ebnou pro jednotlivΘ testovacφ programy jsem m∞°il pomocφ knihovnφ funkce ftime(), je₧ sice nenφ souΦßstφ standardu, je vÜak natolik b∞₧n²m rozÜφ°enφm, ₧e ji implementujφ vÜechny testovanΘ p°ekladaΦe. Testovacφ programy jsem spouÜt∞l na PC vybavenΘm 1GHz procesorem Athlon a 512 MB RAM pod operaΦnφm systΘmem Windows 2000. Ka₧d² program jsem spustil desetkrßt jako jedinou aplikaci v dosovΘm okn∞ a tabulka 3 ukazuje pr∙m∞ry dosa₧en²ch Φas∙.
I kdy₧ jsou dosa₧enΘ Φasy pom∞rn∞ vyrovnanΘ, lze z nich zφskat p°edstavu o kvalit∞ porovnßvan²ch p°ekladaΦ∙.
CO JE TEDY NEJLEPè═?
Je asi jasnΘ, ₧e na tuto otßzku neexistuje jednoduchß odpov∞∩. P°esto z tohoto porovnßnφ m∙₧eme ud∞lat nßsledujφcφ zßv∞ry:
Z hlediska implementace nov²ch rys∙ jazyka C je standardu nejbli₧Üφ BCXP a INT71, ovÜem p°ekladaΦ BCXP zatφm nenφ prakticky pou₧iteln². Na druhΘm mφst∞ je GNU. Ostatnφ porovnßvanΘ p°ekladaΦe jsou z tohoto hlediska v podstat∞ nevyhovujφcφ.
Z hlediska kvality implementace jazyka C++ jsou nejlepÜφ p°ekladaΦe BC6, BCX a GNU.
Z hlediska efektivity p°elo₧enΘho programu vφt∞zφ mo₧nß trochu p°ekvapiv∞ MSVC02, tedy starÜφ verze microsoftskΘho p°ekladaΦe. (Mo₧nß jde o d∙sledek skuteΦnosti, ₧e novß verze p°ekladaΦe implementuje mnohΘ z rys∙ C++, kterΘ p°edchozφ verze opomφjela, a proto se mohla vφce soust°edit na optimalizaci.) Na opaΦnΘm konci spektra najdeme p°ekladaΦ GNU.
Podrobn∞jÜφ Φlßnek, zahrnujφcφ nejen v∞tÜφ poΦet kritΘriφ, ale i ukßzky zdrojovΘho k≤du, struΦn² v²klad o pou₧it²ch testech apod., najdete na Chip CD v rubrice Chip Plus.