Upozornění. Postřehy, prezentované v tomto článku, vyjadřují mé osobními názory a v žádném případě nejsou oficiálním stanoviskem firmy Microsoft.
Tak je to tady. Whidbey Beta 2 je veřejně k dispozici. V této verzi, kromě mnoho jiných novinek, najdete také nejnovější implementaci nového programovacího jazyka C++\CLI. Ambice jsou hodně vysoké. Moto vývojového teamu jazyka C++\CLI je:
„Leave no room for a lower level language on the CLR than C++\CLI.”
Mám za sebou zkušenost s prvním větším projektem v tomto jazyce a musím říci, že C++\CLI je mimořádně kvalitní produkt. Troufám si dokonce tvrdit, že tento produkt bude jedním z tažných koní nové verze Visual Studia 2005. Jazyk MC (Managed C++) prošel, v porovnání s ostatními jazyky v balíku Visual Studio 2005, naprosto zásadními změnami.
Na úvod mi dovolte několik kontroverzních vět.
Můj osobní názor je, že jazyk C++\CLI bude pro .NET stejnou “revolucí” jakou byl jazyk C#. Jsem pevně přesvědčen o tom, že se jazyk C++\CLI stane primárním programovacím jazykem pro platformu .NET. Jazyk C++\CLI je jakousi nadmnožinou jazyka C#. Vše, co je možné vyjádřit konstrukcemi programovacího jazyka C#, je možné vyjádřit i v jazyce C++\CLI. Opačně to ovšem není pravda.
A abych tady jenom neplácal slámu, tak já osobně jsem se již rozhodl. C++\CLI se stal mým primárním programovacím jazykem.
Seznam nových funkcí v nadcházející verzi C++ (pro prostředí unmanaged) a C++\CLI (pro prostředí managed) je skutečně úctyhodný. Nejzajímavější jsou dle mého názoru tyto funkce:
- C++\CLI je „first class citizen“ v prostředí .NET. Éra MC (Managed C++) je u konce.
- POGO – Profiler guided optimalization. Podporováno jak v managed tak v unmanaged.
- Podpora OpenMP 2.0
- STL.NET
- Unmanaged kompilátor souhlasný na 98% podle standardu
- 64-bitový kompilátor pro platformy AMD64 a Itanium
Malý exkurz do nedávné historie C++.
Snažit se prodat C++ jako jazyk nové generace pro platformu .NET bude zajímavý úkol. Známé přísloví praví: “Je velmi snadné důvěru ztratit, ale je velmi obtížné ji získat zpět.” To je dle mého názoru situace, ve které se nachází programovací jazyk C++.
Kompilátor jazyka C++ tvoří nedílnou součást historie firmy Microsoft a je to jeden z jejich nejúspěšnějších produktů. Kompilátor C++ v době př.n (to znamená před .NET, podobně jako značíme př.k. což znamená před Kristem) byl uznáván jako kompilátor, který generuje velmi rychlý a efektivní kód. Napříč C++ komunitou existovala shoda, že Visual C++ má jeden z nejlepších (jestli ne vůbec nejlepší, snažím se nepůsobit jako patolízal) generátorů kódu na trhu. V té samé komunitě také existoval názor, že Visual C++ neodpovídá příliš standardu. Konformita se standardem byla považována (právem) jako zásadní slabina tohoto produktu. Nicméně, VC++ nabízel docela slušnou shodu ze standardem, podle tehdy tajných, citlivých informací, dnes již ovšem odtajněných, byl VC++ 6.0, což byla poslední verze př.n., souhlasná ze standardem na 80%, velmi ucelené vývojové prostředí a kvalitní vývojové knihovny (ATL, MFC).
Nechť je důkazem mých tvrzení tento citát:
“I may complain about Microsoft’s [C++] standards conformance, but it’s a good compiler. If you can get your code through the front end, the back end will generate amazingly efficient executables.”
-- Scott Meyers, Boston, March 2002
Pro nezasvěcené, Scott Meyers je v C++ komunitě uznávaným guru.
Vývoj v komunitě C++ šel ovšem dál. Objevily se nové programovací techniky (metaprogramování pomocí šablon), a na základě těchto technik vznikly velmi výkonné knihovny jako například Boost, Loki či MPL. Tyto knihovny ovšem vyžadovaly kompilátor, který odpovídá standardu.
Zhruba v této době přichází firma Microsoft s platformou .NET. C++ v .NET 1.0 prošel minimálními změnami. Jako samostatný produkt nenabízel C++ kompilátor ve verzi 1.0 žádnou zásadní změnu k lepšímu. Spíše se objevilo mnoho změn v samotném balíku Visual Studio .NET (tři nové jazyky) a mimo jazyk C++. To zavánělo tím, že Microsoft opravdu nemá zájem jazyk C++ dále rozvíjet. Kompilátor C++ ve verzi .NET 1.0 byl, podle oficiálních čísel souhlasný se standardem na 83%. Úsilí bylo evidentně zaměřeno jinam…
S příchodem .NET 1.1 se ovšem vše mění. Microsoft, podle mého názoru, velmi dobře věděl, že si nemůže dovolit ignorovat nejrozsáhlejší vývojovou komunitu na světě, která investovala více jak dvacet let do jazyka C++.
Malá odbočka k číslům. Statistika je ošemetná věc. Jak je známo z televizního pořadu Sedmička, tak pro své argumenty si každý najde svá správná statistická čísla. Můj názor, že je jazyk C++ nejrozšířenějším jazykem vychází z toho, jaké programy dennodenně používám ke své práci. No a také jsem se pokusil najít několik zdrojů na internetu (Developer.com, Programming Language Popularity, Wikipedia, Most popular programming languages -Trend). Snažil jsem se být opravdu objektivní, mně tu nejde o nějaké vymývání mozků :-).
C++ kompilátor ve verzi .NET 1.1 znamenal opravdový milník. Microsoft najal na tuto práci uznávané autority, jako jsou například Herb Sutter či Stenley Lippman. Herb Sutter ihned po příchodu do Microsoftu oznámil, že jeho prioritou je sladit VC++ ze standardem.
Tak se i stalo. Kompilátor C++ ve verzi .NET 1.1 je sladěn ze standardem na oficiálních 98%. Pro ty, kteří by chtěli vědět co to přesně znamená „být sladěn na 98%“, mohu upřesnit, že všechny požadované funkce standardu byly do kompilátoru C++ ve verzi .NET 1.1 (oficiálně též VC++ .NET 7.1) zapracovány, s výjimkou těchto tří:
14. Export keyword
14.6 Dependent name lookup
15.4 Exception specifications
Číslo před názvem funkce odkazuje na paragraf standardu, který popisuje danou funkci. Vše ostatní najdete v kompilátoru VC++ .NET 7.1, a to přesně podle standardu. To v praxi například znamená, že VC++ .NET 7.1 úspěšně zkompiluje knihovny Boost či Loki.
Vše se zdálo být napraveno. Až na jeden malý detail. Microsoft jaksi zapomněl tuto skutečnost sdělit světu. Typický dialog obchodníka a zákazníka mohl tehdy asi vypadat takto:
C++ vývojář: „Připravuje Microsoft novou verzi kompilátoru jazyka C++? VC++ 6.0 je přece jen již pět let na trhu a já nevidím v této oblasti od Microsoftu žádný posun.“
Obchodník: „Ale jistě, že Microsoft v této oblasti pracuje! Mohu Vám nabídnout náš nejnovější kompilátor VC++ .NET 7.1.“
C++ vývojář: „Ale naše firma vyvíjí počítačové hry, a tak nepotřebujeme nástroj pro platformu .NET. Tak nic…“
Díky „brandingu“ .NET Microsoft skutečně znejistěl velkou skupinu zákazníků, a podle toho co jsem četl, tak mnoho firem zůstalo na verzi VC++ 6.0 (dodnes!), protože Microsoft nepodal těmto zákazníkům jasnou zprávu o nejnovějších produktech. Zákazníci spojovali nový C++ kompilátor pouze s jeho rozšířeními pro platformu .NET (Managed C++), a tak chápali tento produkt jen jako nástroj pro vývoj aplikací pro .NET. Ve skutečnosti byl VC++ 7.1 špičkový kompilátor pro unmanaged aplikace a nedodělek pro platformu .NET. Jaká ironie…
Tím jsem se dostal k druhé části problému, a tou je Managed C++ (MC). Tato funkce kompilátoru byla, podle mého názoru, výštěk do tmy. Rozšíření C++ pro prostředí .NET, Managed C++, obsahovala spletitá a záhadná pravidla pro správu ukazatelů, jejichž zvládnutí a rozmotání bylo nad síly normálního smrtelníka. Nechápu, jak tohle mělo ulehčit práci.
Později se objevil výkonnostní problém kvůli tzv. „double thunking“ problému. Hřebíkem do rakve byl další problém, tentokrát mnohem závažnější, kdy veškeré DLL mixed assembly (DLL assembly obsahující jak managed tak unmanaged kód) byly vystaveny tzv. „loader lock“ problému. To v praxi znamenalo, že psát DLL assembly v MC je pouze úspěšný pokus jak si říct o další problémy. Posledním pikantním problémem, který mě napadá, byla nemožnost napsat „verifiable“, managed kód (Microsoft sice poskytnul několika stránkový seznam pravidel, které bylo třeba dodržet, abyste zkompilovali „verifiable“ assembly, ale v praxi se to nikomu nepovedlo, jak se je možné dočíst na Google). Takže to, co si o VC++ 7.1 mysleli zákazníci, bylo bohužel přesně naopak. V oblasti managed byl VC++ 7.1 neúspěchem, v oblasti unmanaged se jednalo s skvělý produkt.
C++\CLI - lze získat důvěru zpět?
C++\CLI, jak jsem zavedl výše, je nový programovací jazyk postavený na jazyce C++. Nejlépe bych to asi vyjádřil takto. Nový kompilátor C++ jsou vlastně dva kompilátory v jednom. První půlkou je klasický C++ kompilátor pro unmanaged aplikace. Ukazatele, malloc, vše při starém. Druhou půlkou je CLI\C++. Tato půlka obsahuje proprietární rozšíření jazyka C++ pro platformu .NET. Je pouze na Vás kterou půlku se rozhodnete používat. Ale zpráva by tentokrát měla být jasná. Kompilátor C++ ve Whidbey (a jak jsem popsal výše i ve stávajících verzích .NET) je možné použít stejně tak pro vývoj unmanaged aplikací jako čistě managed aplikací.
C++\CLI je nekompromisní jazyk pro platformu .NET. Až do této doby totiž měli programátoři v C# jeden zásadní argument proti C++. A to je produktivita. V C++\CLI to již není pravda. C++\CLI je jazyk, nabízející přirozenou syntaxi pro přístup ke službám CLI a knihovně tříd .NET. Posuďte sami:
[AttributeUsage(AttributeTargets::All)]
public ref class HelpAttribute : Attribute
{
private:
String^ url;
String^ Topic;
public:
HelpAttribute(String^ url)
{
this->url = url;
}
property String^ Url
{
String^ get() { return url; }
}
};
[Help("http://www.mycompany.com/…/Class1.htm")]
public ref class Class1
{
public:
[Help("http://www.mycompany.com/…/Class1.htm", Topic="F")]
void F()
{}
};
Přestože se jedná o nový jazyk, tak C++\CLI, jako jazyk vycházející z jazyka C++, nabízí veškeré konstrukce, na které je C+ programátor běžně zvyklý. Například šablony, kopírovací konstruktory, přetěžování operátorů, deterministické uvolnění zdrojů (tzv. RAII idiom), Koenig lookup, mixins (schopnost dědit ze třídy která je parametrem šablony), apod. K některým konstrukcím a obratům bych se rád vrátil v dalším pokračování.
C++\CLI ovšem přináší i některé zásadní změny, na které si musí C++ programátor zvyknout. Rozdílný je například postup konstrukce objektu, volání virtuálních metod z konstruktoru, existuje pouze veřejná (public) dědičnost, není možné deklarovat implicitní (default) parametry apod.
Tímto úvodním příspěvkem jsem se snažil vyjádřit svůj názor, že doba, kdy jazyk C# jednoznačně dominoval platformě .NET je u konce. C# obsahuje podmnožinu vlastností jazyka C++\CLI. C++\CLI je moderní, výkonný jazyk pro prostředí .NET. V C++\CLI se již programátor nezabývá nízkoúrovňovými detaily, jak stále platí v unmanaged C++. V managed prostředí pracuje C++\CLI programátor na stejné úrovni abstrakce jako C# programátor, ale s bohatší sémantikou kterou mu jazyk C++\CLI nabízí.
C++\CLI se musí umět vyrovnat se stigmatem, který zdědil od jazyka C++. Jakmile řeknete C++, tak si mnoho programátorů vybaví ukazatele, složitost, nízkoúrovňové programování, složité nástroje, „steep learning curve“, apod. Netvrdím, že to není pravda pro unmanaged C++. V unmanaged C++ se žádná paradigmata a postupy nemění. Pro prostředí managed je ovšem C++\CLI jazykem na stejné úrovni abstrakce jako C#, liší se pouze syntaxí a možnostmi. Proto si myslím, že se stane tento jazyk v nejbližších letech dominantním jazykem na platformě .NET.
Malá odbočka pro odvážlivce :-). Pokud byste měli zájem o unmanaged C++, tak doporučuji knihu Rozumíme C++. Při čtení této knihy narazíte na zajímavý postřeh. První zmínka o ukazatelích se, v této asi 350 stránkové knize, nachází někde na straně 180 a pak na několika málo následujících stránkách. To proto, že moderní programování v C++ není o ukazatelích, s nimiž je jazyk C++ tak běžně spojován.
C++\CLI je opravdu nekompromisní jazyk pro platformu .NET.