Microsoft a standardy, to je věčné (a nevděčné) téma. Když Microsoft zprznil C++ svým C++/CX (uznávám, že ARC od Applu v zásadě jinak v prostředí C++ okopírovat nešlo), mohl si aspoň dát pozor na chyby. Teď prosím zvolejte třikrát „sláva Microsoftu!“, neboť devět měsíců po nahlášení kritického bugu jsme se konečně dočkali opravy i ve veřejné verzi překladače (jedná se o úniky paměti v lambda výrazech, psal jsem zde o nich nedávno). Přetrvává ovšem možnost přiřadit do „auto&“ dočasný objekt (podle normy to jde jen pro „const auto&“). Reakce Microsoftu byla příznačná: „It's not a bug, it's a feature.“ Tato fráze, často používaná jako vtip, byla myšlena vážně. Ne že by se Microsoftu nechtělo bug opravit, ale takto si poměrně bezpečně zajistí, že i když obejdete nového bastarda (C++/CX), tak v GCC nebo clangu budete mít s překladem problémy.
Podnětem k napsání tohoto článku je zkušenost s Visual Studio 2012 (konečně si všimli, že už není rok 2011), konkrétně kompilací C++ pro CLR. Microsoft kudí chodí, tudy se chlubí podporou C++11 a nové STL. Schválně si zkuste použít byť jen #include <thread> někde v kódu. Překladač vám hned vynadá, že <thread> můžete použít jen při /clr:safe. Toto je bez přehánění jedno z nejdebilnějších rozhodnutí Microsoftu při tvorbě kompilátorů (a příslušných knihoven). Pokud už z nějakého podivného důvodu používám /clr:safe, tak pro vlákna použiju BCL. Naopak <thread> se bude vyskytovat výhradně v kódu, kvůli kterému chci použít /clr nebo /clr:pure.
Asi nastal čas zprovoznit pod Windows clang/LLVM (nebo psát výhradně pro Metro).
P.S. MS také porušuje standard při vracení objektů v lokálních proměnných. Pokud existuje move konstruktor, má se v takovém případě použít. MS kopíruje. To aplikacím rozhodně na rychlosti nepřidá.
Je tady snad někdo se zdravým rozumem, kdo si myslí, že Mrkvosoft se někdy změní? Prznění zavedených konvencí v zájmu snížení přenositelnosti zdrojového kódu na konkurenční platformy bylo, je a bude vždy na prvním místě jeho boje proti konkurenci.
Od té doby, co pro Widle programuji pomocí MINGW jsem se konečně většiny jeho nekonečně únavných chyb a naschválů zbavil.
@3 /clr generuje nativní kód, /clr:pure generuje bajtkód, ale pracuje s neřízenou haldou a zásobníkem (takže tam je STL), /clr:safe je bezpečný mód a je na dvě věci, protože pak už rovnou můžu psát v C#, které je lepší min. v tom, že má Intellisense (C++ ho ve VS 2010 nemělo a ve VS 2012 je zatím zabugované).
@6 Naivně doufám, že lidé jsou rozumní a použijí const.
Obecně MS dělá naschvály, např. dlouho neměl for pro iterátory, jen "for each". Psát přenositelný kód pro prasárny mě fakt nebaví. Teď to už naštěstí mají. Clang zase dlouho neměl lambdy, jen ty své ^, což ovšem s sebou nese další problémy a bugy. Mountain Lion je už má - hurá sláva. Konečně půjde psát přenositelný kód bez maker. Teď už jen chybí C++/CX na Linuxu :-)
Na novém standardu C++11 ještě ani pořádně nezaschnul inkoust a někdo očekává, že snad bude okamžitě a stoprocentně na všech kompilátorech použitelný.
To je ta základní chyba. Samozřejmě, že jakýkoli programovací jazyk a jakýkoli standard se chová tak, že po vydání standardu je třeba několik let čekat, než bude vše na 100 %.
Například GCC stále ještě neimplementuje bez chyby všechny featury programovacího jazyka C, normy z roku 1999 (http://gcc.gnu.org/c99status.html), a to jsme třináctý rok po vydání standardu. A to je, prosím pěkně, C99, nesrovnatelně jednodušší na implementaci než C++11.
Já jsme s implementací C++11 velmi spokojen. Jede velmi rychle a už za pouhý rok po standardu je možné většinu nových featur používat. Pokud za takové čtyři roky, tedy v roce 2015, bude implementace C++11 na 100 % v základních prohlížečích, pak je vše naprosto v pořádku. Pokud dříve, bude to bleskově rychlá implementace C++11 v kompilátorech.
Nevyčítal bych žádnému kompilátoru, že má chyby nebo nedostatky v některých partiích C++11, protože je stále velmi brzy a mají na to čas. Ta implementace není jednoduchá. A je jedno, jestli bude chybovat Microsoft, GCC, LLVM, Intel, nebo kdokoli.
Je třeba vzít v úvahu, že na úpravy kompilátorů jsou velmi drsné nároky co se týká spolehlivosti. Chyba v kompilátoru znamená obtížně hledatelnou chybu v přeloženém programu. Kompilátory musejí především bez chyby přeložit dosavadní standardy. A zasahovat a měnit do kompilátoru se musí opatrně a s tím aby spolehlivost byla zachována.
Je osobní problém každého, kdo nyní chce využívat C++11. Takoví lidé jsou early adopters a musejí zákonitě počítat s tím, že se budou prodírat chybami v implementacích.
Není možné rozumně po kompilátorech (po žádném) nyní požadovat bezchybnou a stoprocentní implenetaci nového standardu.
C++ pro CLR je fail, na tohle se měli od začátku vyprdnout. Na téměř vše stačí kritickou část udělat v normálním C/C++ a v C# si ji zavolat přes P/Invoke nebo jak to jmenuje. Jedinou věc kdy se to hodilo, jsem viděl v Eclipse. Aby Eclipse mohlo používat WPF, tak použili právě C++ pro CLR.
S tím jak se .NET se bude čím dál více přesouvat k server side, jak píšete, tak je na čase zabít i C++ pro CLR.
[10] mi přijde jako velmi rozumný názor. Platí obecně, ale v C++ dvojnásob. C++ je takový nástroj, který se od roku 1983 (možná mě nějaký znalec historie opraví) během 50-100 let změní z C na nečitelnou Javu. Začalo to nějakým rozumným minimem OOP a drobnými výchyty (což opravdu zpřehlednilo kód a zjednodušilo psaní velkých projektů a projektů s přirozenou objektovou hierarchií jako třeba GUI knihovna - v C se tohle samozřejmě taky dá napsat, ale většinou to dá víc práce a není to hezké). Pak přišly šablony, výjimky, přetěžování operátorů, STL, ..., což jsou věci, které se hodí, ale já už je vnímám často jako dost kontroverzní. A často vedou k tomu, že kód správného C++sáře je stejně čitelný jako hardcore C makro zkřížené s důkladnou pointerovou aritmetikou nad 5 rozměrným polem. No a těď C++11, které nezvládají ani autoři překladačů :-) Než to zvládnou, tak přijde C++ 12, 12epsilon, 13, 14, ...až nakonec z toho bude C skřížené z Perlem, Haskellem, Prologem, Javou, ObjectiveC, C# a assemblerem a rozumět tomu nebude ani Bjarne Stroustrup. Tak si myslím, že není dobrá hned být hr hr do nových featur, spíš si trochu počkat (10 let :-) ), až si nové vlastnosti sednou, až budou fungovat ve všech běžných překladačích a teprve pak si rozmyslet, jestli je používat nebo ne.
[15]: Největší průšvih C++ je C. Jazyk C má mnoho velmi špatných věcí, které bohužel z důvodů kompatibility jsou i v C++. Sice několik největších ptákovin C bylo z C++ vyhozeno (jako např. automatické přetypování void pointeru na libovolný typ).
C++ se nejdřív mnoho let vyvíjelo divoce. 15 let jednoduše Stroustrup, Borland a další volně a evolucí pulírovali C++ a přidávali co považovali za užitečné. Teprve po 15 letech přišel první ISO standard C++. A po dalších 12 letech přišel druhý ISO standard C++11. Takže vašich 10 let je určitě splněno.
Nejbližší další standard určitě nebude dříve než 2024–2025. Změny mezi C++89 a C++11 nebyly příliš velké, většina z nich je spíše kosmetické upravení předchozího chování a těch skutečně nových věcí je minimum.
Jako největší tragédii C++ vnímám člověka jménem Andrei Alexandrescu, který z nějakých, pro mě nepochopitelných, důvodů má obrovské slovo. Je zamilován do nesrozumitelných a složitých šablonových struktur. Kdyby tento člověk zmizel z C++, velmi by to prospělo podle mého. STL vnímám jako skutečně nepovedenou část C++. Nulová kontrola parametrů, nevirtuální metody, nulová rozšiřitelnost a ze začátku nezaručené chování u výjimek.
C++ ale jde stále stejným směrem. Maximální rychlost a efektivita výsledné binárky (což implikuje složitost C++), absolutní a stoprocentní zpětná kompatibilita se všemi předchozími standardy. Což je věc, kterou nemůže nabídnout ani C (každý standard C je nekompatibilní s jinými), ani Java.
C++11 opravila spoustu pitomostí jazyka C. Například NULL už nemusí být celočíselná nula, je možné zadávat konečně Unicode literály, konečně je možné výčtové typy (enum) otypovat přesným celočíselným typem, přidána podpora threadů, uvolnila se zbytečně přísná pravidla pro unie.
Mě přijde C++ jako vyvážený, pokud si uvědomím, že v rámci efektivity a rychlosti výsledné binárky je třeba mít pod kontrolou víc věcí, než v jazycích, kde na výsledné rychlosti nezáleží. Pouze STL v některých aspektech vidím jako zpackané – iostreamy; kontejnery co se při nečekaných parametrech složí a zhroutí program namísto ošetření; stringy, které se chovají málo řetězcově, ale spíše je to obalené binární pole.
Osobně mi přijde C++ jako nejlépe vedený standard ze všech programovacích jazyků. Důsledně dbá na jednotnost a přitom komplexnost jazyka, absolutní zpětnou kompatibilitu s předchozími verzemi. Jediným druhým jazykem, o kterém toto mohu říci je Ada. Jinak ostatní programovací jazyky důsledně kašlou na programátora i na serióznost.
[16] "absolutní a stoprocentní zpětná kompatibilita se všemi předchozími standardy"
S tím nemůžu souhlasit, tady jsou dva odkazy:
http://stackoverflow.com/questions/6399615/what-breaking-changes-are-introduced-in-c11
http://stackoverflow.com/questions/6473218/what-differences-if-any-between-c03-and-c0x-can-be-detected-at-run-time
,,Naštěstí celý .NET jde do kytek (kromě serverových aplikací), tak to je celkem jedno."
To jste zjistili kde? V čem se budou psát aplikace pro W8 Metro? Tedy krom HTML5, Javascript a CSS (Což je, mám ten dojem, v tomto případě taky založeno na .NET) což fakt nepokládám za rozumné. Pak by zbylo jen C++ ale co C# a VB a J# ty se jako zahodí? To my teda vysvětlete!
[18] Jaga: O WinRT jste neslyšel? Celé W8 a Metro na tom stojí. Javascript, C++ a i ten C# budou nad WinRT a plnohodnotný .NET na W8 Metro aplikacích v podstatě nebude. .NET je tak v podstatě legacy GUI a jeho hlavní využití se přesouvá na server.
Tohle je už věc z minulého roku, trochu jste zaspal. A ten J# je už naprosto mimo.
[19]lopata
Pardon asi jsem to špatně pochopil. Já myslel že WinRT je od Windows Runtime a tedy jsou to nějaké knihovny. Podle vás tedy WinRT obsahuje i JIT Compilátor a jiné věci nutné pro běh mezikódu? Nebo bude z C# překládáno přímo do binárek?
V tomto článku: http://babel.blog.root.cz/2011/09/19/windows-8-a-winrt/
Se píše ,že:,,.NET jazyky můžou k WinRT přistupovat přes wrapper" tudíž jsem usoudil ,že .NET bude stále nutný. To se omlouvám....
Proč je J# mimo? :)
[17] Ale samozřejmě, že nová klíčová slova překryjí stejnojmenné proměnné a makra, která si definujete ve starém C++ kódu.
Konkrétní hodnoty vrácené operátorem sizeof nikdy norma nezaručovala, takže kód závislý na přesných hodnotách vrácených operátorem sizeof je implementation dependent.
Atd.
Ale je třeba hodně šťourat prstíčkem a moc moc se snažit vší silou a přemýšlením, aby člověk našel aspoň náznak nekompatibility mezi C++11 a předchozí normou, co? To je panečku kompatibilita!
Zatímco mezi různými standardy C, nebo různými verzemi Javy, či jakéhkoli vámi zvoleného programovacího jazyka má programátor plné kecky toho aby projel celý svůj program a našel tam skyté chyby.
xxxxxxxxxxxxxxxxxxxxx
[20] Já vím, proč je tak STL napsaná. Právě proto STL nepoužívám vůbec, protože si vážím svých nervů a času.
A to ještě nevíte, jak vypadala STL na začátku, kdy se dokopávali autoři STL k tomu, aby aspoň nějaké předpoklady zachovávala.
[21] JaGa: ano, ale nebude to plnohodnotný .NET, ale nějaká okleštěná verze, dalo by se asi přirovnat k Silverlightu. V tom také píšete C# a máte BCL ale celý .NET to není.
J# už je léta nepodporovaná věc, která sloužila jen k tomu, aby se důležití zákazníci MS, kteří používali tu Microsoftí Javu snáze dostali k .NET a nemuseli všechno přepisovat do C# hned. Jakmile to časem přepsali tak to MS zaříznul.
Pokud chcete Javu nad .NET tak používejte open source IKVM. Vychytaná a hlavně udržovaná záležitost v podstatě jen jedním člověkem, malý zázrak.
[16] ... STL vnímám jako skutečně nepovedenou část C++. Nulová kontrola parametrů, ...
To nějak nechápu.
Nemluví se právě jako o jedné z výhod šablon o tom, že se jimi nahradila makra s tím, že u šablon už může překladač právě parametry kontrolovat?
To, že se s tím pak dají stavit naprosté zhůvěřilosti teď nehodnotím ...
@18 HTML5 aplikace ve Win8 jedou na Chakrou. Když už o něčem píšu (navíc kriticky), tak si aspoň zjistím fakta, ne? J# je dobrá vykopávka, akorát ukazujete, že o .NETu máte nulové znalosti (o Win8 radší pomlčím). Těžko tady bude mít někdo čas vysvětlovat elementární záležitosti, doporučuju Google.
[24][27] Je rozhodnutím tvůrců STL, že rychlosti obětují vše. Tedy i rozšiřitelnost, bezpečnost, spolehlivost – to vše šlo do háje.
Takže například iostream like objekty nemají virtuální metody, aby se ušetřilo 0,0000000000001 sekundy při práci s diskovými soubory třeba.
Řetězec není řetězec, není to kompaktní string, je to jednoduché pole bajtů (které jsou někdy brané jako pole char, jindy jako wchar_t, případně si můžete dodělat traits pro další typy). Ale nikdy se to nechová jako celek – programátor prostě dostává pole a musí si hlídat jako znakové kódování (protože basic_string šablona je zkrátka binární pole, nikoli textový řetězec). Stringy v STL nejsou abstrakcí textových řetězců, ale abstrakcí binárních polí stejných typů zakončených nulou (nebo jinak, jak si napíšete v traits).
Kontejnery typu vector, list, atd. nekontrolují předávané parametry (s výjimkou at() metody), takže jakmile chcete prvek mimo rozsah, podle normy je legální, když se program nekontrolovatelně zhroutí, nebo se rozesere, nebo cokoli.
Přitom u kontejnerů je argument rychlosti irelevantní. Pokud budu potřebovat maximální rychlost, napíšu si svůj kontejner na míru. Ten bude klidně 2 ×, možná i 10 × rychlejší než cokoli co jde přes STL. Konkrétní kontejner na psaný na míru včetně vlastních alokací bude vždy rychlejší, než obecná implementace. Když nepotřebuji šetřit každou pikosekundou, což v 99,999999 % nepotřebuji, pak uvítám kontejnery, které se chovají spolehlivě a při nekorektním požadavku vyhodí třeba výjimku a program jede dál.
Napsat si náhradu vlastních kontejnerů za STL je otázkou velmi krátkého času. Ona toho STL zase moc neumí.
Takže STL beru jako defektní od výroby a fakticky ho nepoužívám. Pokud potřebuji maximální rychlost, napíši si to konkrétně – a vždy to bude rychlejší, než STL. Takže STL nenabídne ani maximální rychlost, ani bezpečnost, ani spolehlivost.
[31] A kolik firem si muselo napsat vlastni JVM, aby to vubec fungovalo :-) Kdyz ani Sun toho nebyl schopen. V nasledujicim prispevku autor pise, ze soucasne zmeny v C# jsou jak "dort pejska a kocicky". Ne vse se mi zamlouva, ale neni to zatim velky prusvih a alespon je videt nejaky vyvoj kupredu. Ovsem Java (nemyslim jen jazyk, ale cela platforma) je zase jak kdyz to delali Pat a Mat ze serialu A je to !
[31] Co já vím, tak se většinou definuje minimální potřebná verze, na čemž nevidím nic divného. Pokud chce někdo konkrétní tak to je specifická záležitost (prasárna). Jinak na různých JVM je schopna běžet překvapivě většina programů. Ostatně - mají ty "nesprávné" JVM certifikaci? Jestli ne, těžko se divit potížím.
[32] Určitě každá druhá co vyvíjí něco v Javě, že? :-D Ano, i SUN měl/má dost bugů v JRE/knihovnách ale i tak nechápu čeho nebyl schopen?
Zaujimalo by ma co pouzivate namiesto STL kontajnerov a inych funkcionalit z STL kniznice ked je uz taka nevyhovujuca ze sa snou vazne neda pracovat lebo ma nedostatocnu kontrolu parametrov a totalnu absenciu virtualnych metod. Neviem si predstavit ze budem implementovat svoj vlastny std::vector a bude robustnejsi, rychlejsi a vsestrannejsi ako ten z STL. Este som sa nestretol so situaciou kedy mi chybala virtualna metoda, naopak, pozrite si optimalizovany release kod tychto template-ovych implementacii.
Pripada mi to ako vyplakavanie nad assemblerom ze nedokaze vykreslit kruznicu na jednu instrukciu a skompiluje kod kde sa zavola call rutinka aj ked na stacku nie su vsetky data ktore potrebuje.
[32] Přesně. Java i přes svou údajnou "konzervativitu" mi přijde natolik rozdrobená, že jsem velmi překvapen, když něco složitějšího a specifického (třeba internetové bankovnictví KB) funguje i s novějším updatem. Zažil jsem případ, kdy jsem opravoval právě toto rozbité bankovnictví, které nechalo zamrznout stránku v prohlížeči. Po rozpravě s technikem v KB mi bylo doporučeno nainstalovat starší Update - a voilà, všechno zase funguje. :)
U C# je těch majoritních verzí jen několik, většina programů běží buď na verzích od 2.0 do 3.5 (které jsou všechny zahrnuté v jednom balíčku - 3.5) nebo teď nově na verzi 4.0, hlavně na Client Profile, kterýžto bude ve výchozím stavu zahrnutý ve Windows 8. A většina změn se stávajícího kódu nedotkne.
@ll - Nechápu! .NET začínal před dvanácti lety a to měl počíták CPU PIII nebo Duron a 128 až 256 MB RAM. Teď má kdejaký laciný telefon dualcore a 1GB operačky, stolní počíták minimálně dvoujádro, já mám 4 jádro s HT a 32GB ram.
Ale TEĎ naráz M$ křičí, že je .NET nenažranej! WTF? V .NETu dělám a jsem rád, že se nemusím starat o grabage collection a můžu se prakticky soustředit je na úkol. Nemusím myslet na pointry. Kdybych se chtěl zabývat programováním a né psaním programu, dělal bych v brainfucku :-/ Někdo mi to vysvětlete. C++11 je sice krok správným směrem, ale pořád milion světelných let pozadu za Javou. Jinak řečeno, C++11 je jako ty chaluhy, které na začátku vyplavilo moře a Java (i.NET) alespoň už jako první opolidi.
@36 Jseš 20 let pozadu. Kdo dnes v C++ používá explicitní ukazatele? Správa paměti vychází nastejno. Něco si o C++ přečti, ať už ze sebe příště neuděláš vola.
C++11 je před Javou a .NET v rychlosti vývoje i binárky (netýká se pseudoprogramátorů). Jen ta standardní knihovna je trochu menší.
Autor se zabývá vývojem kompilátorů a knihoven pro objektově-orientované programovací jazyky.
Přečteno 36 261×
Přečteno 25 412×
Přečteno 23 832×
Přečteno 20 213×
Přečteno 17 921×