Portál AbcLinuxu, 23. dubna 2024 22:34


Nástroje: Začni sledovat (2) ?Zašle upozornění na váš email při vložení nového komentáře.

Vložit další komentář
15.11.2011 23:30 Let_Me_Be | skóre: 20 | blog: cat /proc/idea/current | Brno
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Odpovědět | Sbalit | Link | Blokovat | Admin
Silně relevantní materiál: http://exceptionsafecode.com/index.html
Linked in profil - Můj web - Nemůžete vyhrát hádku s blbcem. Nejdřív vás stáhne na svoji úroveň a pak ubije zkušenostmi.
16.11.2011 10:49 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Dík.
17.11.2011 16:23 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
V té přednášce doporučují používat všade RAII.

To zní celkem logicky a docela pěkná je i představa, že každý objekt má validně alokovaný resource, nebo se vůbec nevytvoří. Nadruhou stranu by mi to mohlo v některých případech asi dost zesložitit konstruktory, zvlášť pokud jde o objekty generované z factory, etc...

A třeba takový std::fstream má jak RAII konstruktor, tak ale i non-RAII funkce.

Co si myslíte o použití RAII?
17.11.2011 16:56 Let_Me_Be | skóre: 20 | blog: cat /proc/idea/current | Brno
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Ono je to prave naopak. Kdyz mas ne-RAII kostruktor, tak si zeslozitujes kod ktery ten objekt bude pouzivat, protoze presouvas zodpovednost o uroven nahoru.
Linked in profil - Můj web - Nemůžete vyhrát hádku s blbcem. Nejdřív vás stáhne na svoji úroveň a pak ubije zkušenostmi.
18.11.2011 14:29 Sten
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Pokud vám to zesložiťuje konstruktory, tak asi nepoužíváte RAII. Jeden ze základních věcí RAII je to, že jeden objekt má právě jeden zdroj. Potom jakákoliv chyba při alokaci dalších zdrojů uklidí všechny předchozí zdroje.

Streamy v STL jsou takové šité horkou jehlou (např. vůbec nepoužívají alokátory), takže podle nich bych si moc nic nemyslel.
18.11.2011 16:39 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Ok, asi bude lepší, když budu konkrétní.

Píšu třídu pro práci z (netradičně) šifrovaným souborem, s API podobným jako všelijaké ty streamy (akorát bych rád RAII). Takže pracovní postup je: 1) otevřít soubor 2) nastavit velikost zapisovaných dat (toto je nutné předem) 3) nastavit šifrovací klíč 4) zápis dat 5) zavřít soubor. Jde mi o to, kam dár krok 2) a 3). Musí být v konstruktoru? To by totiž mělo zaprvé dost důsledků pro vnitřní API (plyne to z technických detailů věci, v podstatě by mi tam vznikaly těsné závislosti), zadruhé by pak konstruktor měl už asi 6 parametrů, z čehož jsem mírně nervózní, a zatřetí musí být velikost zapisovaných dat známá už před vytvořením objektu (ne, že by to nějak drasticky vadilo). Dodám jen, že kroky 2) a 3) nealokují žádné další zdroje ani nepotřebují po sobě nějak uklidit, jediný problém je v tom, že se musí provést před tím, než je možné provádět I/O, čili je to určitá zodpovědnost.
18.11.2011 17:21 Sten
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Šifrovací klíč by měl jít do konstruktoru. Asi by bylo lepší pro něj vytvořit vlastní třídu (která bude dělat samotné šifrování), obzvlášť pokud vyžaduje více než jeden parametr.

Krok 2) můžete udělat až těsně před začátkem zápisu. Protože tipuju, že spíše půjde o nějaký buffer, je jednodušší si nějaký buffer alokovat v konstruktoru (třeba klasických 4096 bajtů, možno i přidat jako nepovinný parametr) a při jeho zaplnění (či ručním flushnutí, které provedete i při uzavírání toho souboru) jej zašifrovat a zapsat na disk. Pokud opravdu potřebujete vědět délku celého souboru (proboha, jaký algoritmus to je?), tak ji taky přidejte do konstruktoru. I když v tomhle případě by bylo lepší to udělat jednou funkcí, aby se zaručilo, že skutečně dostanete tolik dat, kolik vám je nahlášeno.
18.11.2011 17:29 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Šifrovací klíč by měl jít do konstruktoru. Asi by bylo lepší pro něj vytvořit vlastní třídu (která bude dělat samotné šifrování), obzvlášť pokud vyžaduje více než jeden parametr.
Jj, budu to asi muset celý rozdělit do více objektů, minimálně vnitřně...
Pokud opravdu potřebujete vědět délku celého souboru (proboha, jaký algoritmus to je?)
Steganografický ;-) Tam prostě potřebuju dopředu vědět, kolik dat ukládám.

No, dík za tipy, zkusim si s tim nějak poradit...
18.11.2011 19:10 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
A jinak co se týče I/O funkcí, když bude třída z nějakého důvodu muset zapsat/přečíst menší počet bajtů než bylo požadováno, mám házet výjimku? Asi jo, ne? Vzhledem k tomu, že velikost dat ke čtení (při čtení) a volné místo k zapsání (při zápisu) budou předem známy...
18.11.2011 22:40 Sten
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Učebnicové řešení by bylo házet výjimku a přidat konstantní metodu, která umožní ověřit, že dat je dost — ověřením existujícího stringu nebo vrácením minimální délky řetězce, či nejlépe obojím.
16.11.2011 00:36 limit_false
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Odpovědět | Sbalit | Link | Blokovat | Admin
Kolem implementace vyjimek v gcc je hodne cerne magie:

Výjimečně drahé výjimky (C++)

"GCC se evidentně řídí filosofií, podle které je exception, tedy výjimka, skutečně něco výjimečného a že v drtivé většině půjde kód "běžnou" cestou. Proto generuje kód, jehož běžná cesta není o nic (0.00prd) delší, než cesta bez ošetření chyb."

Presne tak. Kdyz kod haze tisice vyjimek, v API neco skripe. Tj. nepouzivat stylem "getObjectForIdentifier(objId)", ktera haze vyjimku, kdyz objId neexistuje, ale zaroven se pouziva na test existenci objektu.
16.11.2011 12:57 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Výjimky v C++ jsou velmi levné.

Nestojí vůbec nic. Catch blok stojí jednu jedinou strojovou instrukci navíc v cestě kódu, který nevyhazuje výjimku. Tedy na dobrém kompilátoru.

Kromě toho autor tohoto článku si cestu vyhození výjimky hodně zdražil. Vyrobil výjimku, která alokuje string a alokace je poměrně hodně pomalá operace.

C++ ale umožňuje mnohem levnější výjimky pokud o to budete stát. C++ netrvá na tom, že výjimky musí být potomkem std::exception, ale vyhodit můžete jakýkoli typ, dokonce i int. Nebo vlastní třídu, která nebude obsahovat typ std::string.

Pokud si autor chce optimalizovat na rychlost, pak měl benchmarkovat jednak vyhození výjimky typu int a jednak vyhození typu třída, který obsahuje pouze int datový člen s kódem chyby, nikoli řetězec.

Další možností je vyhazování předvyrobené instance. V zásadě jediná možnost, pokud chcete mít jistotu, že výjimka typu out_of_memory projde dobře, protože pokud budete v případě nedostatku paměti vyhazovat výjimku typu std::exception, která potřebuje alokovat paměť pro string, není to úplně to pravé ořechové.
16.11.2011 22:24 limit_false
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Plati jen pro vyjimky kompilatoru implementovanem na platforme virtualni masiny sfericke kravy ve vakuu.
16.11.2011 07:44 osel
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Odpovědět | Sbalit | Link | Blokovat | Admin
Argument pro použití výjimek není ani tak rychlost jako spíš přehlednost kódu. Když se dobře použijí, tak to pomůže hodně. Není potom potřeba hledat chyby u každého volání funkce, ale výjimku můžu nechat probublat až na místo, kde má smysl jí řešit. Na druhou stranu je ale nutné dokumentovat API a taky přesvědčit ostatní, aby výjimky také používali. Např. asi nejhorší mi přijde, když pak někdo volá API s výjimkami tímto stylem:
bool foo(Something ** ret) {
  try {
    ret = barThrowsSomething();
    return true;
  } catch(...) {
    return false;
  }
}
Saljack avatar 16.11.2011 09:27 Saljack | skóre: 28 | blog: Saljack | Praha
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Odpovědět | Sbalit | Link | Blokovat | Admin
Zajimalo by me, proc se Qt skoro vubec vyjimky nepouzivaji? Planuji to nejak zmenit? Nevite nekdo?
Sex, Drugs & Rock´n Roll.
David Watzke avatar 16.11.2011 10:39 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Viz tady a tady
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
16.11.2011 10:46 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Afaik z historických důvodů...
16.11.2011 12:25 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Protože autoři Qt nesnášejí C++ a nijak se tím netají. Zato prachy mají rádi natolik, že byli schopni skousnout i C++, ale nezůstalo to bez následků.

Knihovna Qt je nenávistí autorů Qt k C++ poměrně hodně poznamenaná. Od snahy udělat si C++ trochu jako ObjectiveC, díky čemuž bylo nutné dát speciální preprocesor až po nevyužívání dobrých featur C++ jako jsou třeba výjimky.
David Watzke avatar 16.11.2011 12:42 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Co to je za psychoblábol?
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
16.11.2011 12:47 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Nějaký argument by nebyl?

Toto píší sami autoři Qt. Já jsem nic nepřidal. Před cca třemi roky, když jsem se zabýval Qt autoři na titulce psali, že nesnášejí C++ a milují ObjectiveC. Protože ale vyhodnotili, že ObjectiveC nemá perspektivu, zato C++ ano, rozhodli se alespoň, že si přidají prvky ObjectiveC do C++ a vytvořili preprocesor. Následně nepoužívali nic, co ObjectiveC nemá. A výjimky tehdy nebyly.

Nicméně autoři Qt asi byli pod vlivem když to psali.

Prostě někteří lidé nemají v plánu být politicky korektní za každou cenu a autoři Qt zřejmě necítili potřebu psát diplomaticky.
David Watzke avatar 16.11.2011 12:53 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Argument je k nalezení o kousek výše, vyjadřuje se tam jeden z vývojářů a vysvětluje to.

Máš taky nějakej odkaz?
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
16.11.2011 13:00 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Já perfektně rozumím tomu, že autoři Qt v okamžiku, kdy chtěli Qt prodat se museli začít tvářit seriózně. Tedy odklidit z Qt webu všechny upřímné zpovědi, které tam dosud byly.

Odkaz jistě najdete někde v archívu. Doporučuji google.

16.11.2011 14:36 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Nevim, jestli co říkáš, je pravda, ale každopádně proč to sem píšeš? Koho zajímá osobní postoj autorů Qt k různým featurám C++? API Qt je veřejně a dobře známé (včetně MOC) a každý si ho může zhodnotit, jestli je nebo není dobré (a z jakého hlediska). Jaké osobní důvody vedly autory k jeho napsání je už podružné...
16.11.2011 10:07 ::: | skóre: 14 | blog: e_lama
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Odpovědět | Sbalit | Link | Blokovat | Admin
jako hlavni problem vyjimek bych nevidel rychlost ale binarni kompatibilitu.

treba kdyz knihovna vyhodi vyjimku, zachyti ji program kdyz byl zkompilovany jinym prekladacem/jinou verzi stejnyho prekladace?

Sam jsem s timhle sice moc neexperimentoval ale z toho co jsem nasel na netu to nevypada moc optimisticky...
16.11.2011 10:37 Ivan
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
> treba kdyz knihovna vyhodi vyjimku, zachyti ji program kdyz byl zkompilovany jinym prekladacem/jinou verzi stejnyho prekladace?

Na to je tezka odpoved. Ale treba g++ ver 4.2 neni kompatibilni s novejsimi verzemi. Napriklad knihovna OCCI od Oracle funguje pouze na RHEL5. Na vsech novejsich distribucich vyhozeni vyjimky vyvola SEGFAULT.

Dalsi pikantni veci pri je pouzivani vyjimek v multithreaded aplikacich. Muze se vam stat, ze vyhozena vyjimka bude odchycena v kontextu uplne jineho vlakna. Proto by kazda metoda run mela obsahovat "catch(...)" a nemela by poustet vyjimky dal.

16.11.2011 12:36 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Doporučoval bych neztrapňovat a nedáváat tak okatě najevo, že o tom houby víte.

Výjimka nikdy nebude zachycena v kontextu jiného vlákna.

Příště prosím piště o věcech, kde máte nějaké znalosti.
16.11.2011 18:17 Tom
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
No ... v c++0x vyjimku muzete zachitit v kontextu jineho vlakna, jsou tam na to 'nastroje'.
16.11.2011 18:33 Sten
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Ale jenom tak, že se „ručně” přenese a znovu vyhodí.
16.11.2011 20:22 Kvakor
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Dalsi pikantni veci pri je pouzivani vyjimek v multithreaded aplikacich. Muze se vam stat, ze vyhozena vyjimka bude odchycena v kontextu uplne jineho vlakna.
Takhle fungují v multithreaded aplikacích signály (tedy minimálně v Linuxu) a i když je možné, že se kdysi vyjímky mohly implemenotovat pomocí nich, žádný moderní runtime nic takového, pokud vím, nedělá.
18.11.2011 14:34 Sten
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Je sice pravda, že obecné signály jako SIGTERM může dostat libovolné vlákno (ale lze to poměrně snadno manipulovat), tak výjimkové signály (SIGSEGV, SIGILL ap.) dostává jen vlákno, které výjimku způsobilo. Takže pochybuju, že to tam kdy bylo.
16.11.2011 11:10 prqek | blog: prqek
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Matně si vybavuju jakýsi problém při zachytávaní vyjímek, které vznikly v jiném modulu. Detaily už dávno sežrala příšera zapomětlivost, ale vzpomínám si, že jedinné řešení, které jsem tenkrát vymyslel, spočívalo v zachytávání všech vyjímek a hacku, kterým jsem se dostal k interním strukturám generovým g++ s typem vyjímky a následým if nebo case. Celkem prasárna...
16.11.2011 12:27 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Binární kompatiblita není zaručena ani v C bez výjimek.

Programovací jazyk není od toho, aby spolupracoval s jinými jazyka, pokud mu to výslovně není řečeno.

Ale mezi námi, myslíte si, že pouhé předání struktury v C je binárně kompatibilní s jinými jazyky? Není. I to se může rychle zhroutit.
16.11.2011 14:28 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Ale mezi námi, myslíte si, že pouhé předání struktury v C je binárně kompatibilní s jinými jazyky? Není. I to se může rychle zhroutit.
Samozřejmé to není (padding,...), nicméně dá se to zajistit.
16.11.2011 14:31 ::: | skóre: 14 | blog: e_lama
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
zarucena neni, ale v praxi kdyz si dam trochu pozor (a treba nepredavam struktury hodnotou) tak muzu navrhnout C rozhrani ktery funguje v 99% pripadu.

U vyjimek je to horsi... Kdyz vezmu v uvahu nejakou knihovnu, treba Qt, tak si myslim ze by byla nepouzitelna pokud by ju mohli pouzit jenom aplikace zkompilovany stejnym prekladacem, ve stejny verzi a se stejnyma prepinacema...

16.11.2011 14:45 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Je toho víc na co si musíte dávat pozor. Ne nadarmo unixoví tvůrci věděli, že cokoli kromě plain textu je někde nějak nekompatibilní.

Jen namátkou, co zarovnávání členů struktur? Co když jeden kompilátor zarovná na bajty a knihovna předpokládá zarovnané na násobky 8 bajtů třeba? Pak jste v zadeli i s pointry na struktury.

A tak bychom mohli o problémech mluvit dál a dál.

Kompatibilita mezi knihovnou a programem není zaručena ani v C.

Proto existují binární standardy, které toto zaručují, ovšem Linux a unix je víceméně považuje za zbytečné. Následně se oddává přepodkladům, že něco mezi knihovnami a programem je kompatibilní, třeba i na úrovni C, ale je to bláhovost.

Linux zachraňuje ve sladké nevědomosti jenom to, že používá víceméně jen gcc kompilátor a většina distribucí je zkompilována sakumprásk velmi podobnými optiony a verzemi kompilátoru.

--

Problém binární nekompatibility C++ high tech featur je prostě problém pro všechny milovníky LGPL.

Nicméně ani LGPL nikomu nebrání zkompilovat knihovnu stejným kompilátor, stejnoou verzí a stejnými přepínači jako program. Jen Linux bude mít problém, pokud chce sdílet knihovny globálně a odděleně od programu – respektive s touto ideou. Je to řešitelné cestami ke knihovnám, ale už je vidět, že ten koncept dře.

--

Není a neexistuje žádný programovací jazyk, ve kterém by bylo zaručeno, že knihovna a program budou kompatibilní. Ani v C.

Kompatibilita je zaručena pouze, pokud si stanovíte binární API. Na druhé straně každé binární API znamená zpomalení programu a neefektivitu, protože přichází režie standardního volání.

Tudíž primárně každý efektivní programovací jazyk nestanovuje binární API, ale spíše dovoluje u některých funkcí ho zavést.

Binární kompatibilita je drahá a většinou nepotřebná v rámci programovacího jazyka. Navíc je nutné jí zavést pro každou platformu jinak.
16.11.2011 12:40 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
"treba kdyz knihovna vyhodi vyjimku, zachyti ji program kdyz byl zkompilovany jinym prekladacem/jinou verzi stejnyho prekladace?"

tohle bych nikdy nezkoušel

Protože stejně jako nemáte zaručeno, že C knihovna správně bude fungovat s programem přeloženým dokonce stejnou verzí jen s jinými optiony kompilátoru, tak totéž je C++.

Jinak řečeno, jen sebevrah se pokouší o toto.

Výjimky nejsou binárně kompatibilní, ale stejně tak nejsou binárně kompatibilní ani struktury, ani řada věcí z C.

16.11.2011 14:31 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Výjimky nejsou binárně kompatibilní, ale stejně tak nejsou binárně kompatibilní ani struktury, ani řada věcí z C.
A to je co za argument? Vy zas bijete černochy? :-D

Že něco taky nefunguje v C je sice možné, ale to nijak neovlivňuje fakt, že binární nekompatibilita C++ exceptions je dost problém.
16.11.2011 14:52 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Omlouvám se za svou drzost, že jsem si dovolil napsat jak to je. Za trest teď sním svačinu a odpustím si své oblíbené viržínko. Nebrečte, sám jste si to způsobil!

Binární nekompatibilita exceptions není žádný problém. Problém je programátor, který si myslí, že jediná nekompatibilita mezi binárními součástmi modulu jsou C++ exceptions.

Ve skutečnosti kdo umí, tak nekompatibility vyřeší, protože těch možných nekompatibilit jsou stovky na všech možných stranách ve všech možných vlastnostech. A kdo neumí, problémy si zaslouží.

Navíc necítím potřebu kompilovat knihovny a program jinými kompilátory, když se jedná o stejný jazyk.

A jinak už mě nebijte. Fakt se stydím, že jsem měl dokonce drzost napsat ještě tento příspěvek po Vaší káravé výtce. Opravdu nerad bych měl na svědomí černochy – na to jsem humanista.
16.11.2011 15:04 ::: | skóre: 14 | blog: e_lama
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Navíc necítím potřebu kompilovat knihovny a program jinými kompilátory, když se jedná o stejný jazyk.

ted uz zacinam chapat tvoje argumenty, ale pripada me ze to trochu popira smysl knihoven kdyz kazdy program musi mit svou verzi...
16.11.2011 15:06 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Omlouvám se za svou drzost, že jsem si dovolil napsat jak to je.
Já proti tomu nic nenamítal, ono to tak opravdu je (ano, pane Ponkrác, máte pravdu!), já jen namítal, že to je irelevantní.
Problém je programátor, který si myslí, že jediná nekompatibilita mezi binárními součástmi modulu jsou C++ exceptions.
Ale vždyť to tady přece nikdo netvrdil.
Ve skutečnosti kdo umí, tak nekompatibility vyřeší
Ok, chceš použít knihovnu, od který máš k dispozici binárku zkompilovanou kompilátorem Y a ty používáš kompilátor X. Máš jinou možnost než přejít na kompilátor Y, přestože z různých důvodů nechceš?
Fakt se stydím, že jsem měl dokonce drzost napsat ještě tento příspěvek po Vaší káravé výtce.
O tom silně pochybuju :-D
16.11.2011 12:35 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Odpovědět | Sbalit | Link | Blokovat | Admin
Otázka je položena špatně. Použít/nepoužít je otázka, která k odpovědi na jakoukoli vlastnost jakéhokoli jazyka nevede.

Správná otázka je "kdy použít výjimky".

Sám jste si správně změřil, že používání výjimek nic nestojí pokud výjimka nenastane. A to sjte ještě měřil na gcc, tedy na kompilátoru, který dává velmi neoptimální a špatný kód.

Když si přidáte, že ošetřování chyb bez výjimek, kdy chyba proleze několika vrstvami API - pak zbavení se kódu k testování návratové hodnoty - naopak program zrychlí. Protože se zbavíte chybového testování a vše vyřídíte ve výjimkách, což proleze efektivněji a rychleji.

Výjimky mají obrovský benefit také ve faktu, že kód je daleko přehlednější. Zkuste si v nějakém programu opravdu důkladně a úplně testovat všechny chyby. Pokud užitečný kód, který není testováním chyb zabere více než 30 % kódu, děláte to většinou špatně a něco jste za chyby zapomněli otestovat. Najít pak užitečný kód mezi spoustou balastu řešící různé další stavy pak není jednoduché.

Většina lidí ale více méně důakldné testování chyb ignoruje, takže pokud program nepoužívá výjimky, je téměř jisté, že vše není ošetřeno.

Výjimky také jako chyby nejdou ignorovat. To je také obrovský benefit.

A obrovský benefit k přehlednosti je také ten, že nemusí zatěžovat API funkcí chybovým indikátorem.
16.11.2011 12:52 ondra.novacisko.cz
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Ono těch benefitů je mnohem víc. Vyjímky se mohou dědit, takže lze na implementační straně rozšířit rozhraní o další pestrou sadu vyjímek bez ztráty kompatibility se starším kódem.

Další výhodou je třeba lepší přenositelnost. Souvisí to s děděním. APIčku mám výjimku FileOpenException, kterou v Linuxu dědí LinuxFileOpenException a ve Windows WindowsFileOpenException. Multiplatformní software se chyjí na tu obecnou výjimku, pokud kód upravím na jednu platformu, mám šanci z výjimky vytřískat víc informací, například GetLastError() u Windows a errno u Linuxu.

Všechny výjimky v mých knihovnách mají povinně anglický popisek (který lze v případě potřeby volitelně lokalizovat) a reportují i místo vzniku. Pokud kód vyhodí neočekávanou výjimku, poskytne o aplikace mnohem víc informaci, než prosté SIGSEG nebo SIGABORT. V určitých situacích umím dokonce výjimky řetězit po vzoru Java-reason, pak ten popis chyby může mít i několik řádku popisného textu chyby.

Dík za článek. Ještě by to chtělo vzít u MSVC. Tam budou podle mne čísla horší. MSVC kód s výjimkami je v každé funkci delší o dvě tři instrukce definující rámec. Každá výjimka pak musí projít přes RaiseException, což propadne až do jádra. Výhodou je jednotný systém výjímek a možností na ně reagovat, a to i v jiném DLL. Nevýhodou je, že bude nejspíš znatelně pomalejší.
16.11.2011 13:11 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Nikdy jsem nebyl přítelem lokalizace popisků ve výjimkách. Ale to je věcí názoru.

Výjimka pro mě není interface pro komunikaci s laickým uživatelem. Chybové zprávy pro běžné situace nemá laický uživatel programu podle mě vůbec z výjimek dostávat jako přímé zprávy.

Výhodou RaiseException je jednotný systém pro debuggery. Každý debugger ví, že se jedná o výjimku a to v jakémkoli programovacím jazyce. Výhodou je, že je stanoven binární standard výjimek pro všechny Windows programy.

RaiseException nemusí propadnout do jádra a většinou nepropadne. Všechny datové struktury, které RaiseException potřebuje jsou dostupné v user režimu. Takže příliš pomalé to není.

Gcc na Windows RaiseException nepoužívá, jede si po svém.

MSVC umožňuje dobře řídit, jak bude zacházet s výjimkami. Detaily přesahují rámec příspěvku do diskuse. Zkráceně by šlo říci, že C++ kód pod Windows chytá nejen C++ výjimky, ale také hw výjimky z kódu jádra Windows. Je to efektivnější a šikovnější náhrada signálů známých z unixu. Pokud nějaký thread způsobí problém, ten samý thread také dostane výjimku. Nestane se, že by program byl napálen signálem a nějaký thread by pak koukal jako tele z jara, co se děje. Navíc je tak možné ošetřit i stavy, které v signálovém systému unixu znamenají jedině kill, jinak se nedají řešit.

Díky tomu MSVC předpokládá, že jakákoli strojová instrukce může vyhodit výjimku. Lze tohle chování přenastavit i na chování, že bude chytat pouze C++ výjimky - a pak optimalizuje ála gcc, že nevytváří rámce tam, kde C++ nemůže vyhodit výjimky, kód je efektivnější. Ale odstřelení hw výjimkou z jádra pak je fatálnější.

Gcc jsem na Windows přestal používat také proto, že nespolupracuje s výjimkovým systémem Windows a o všechny tyhle finesy přichází.

17.11.2011 15:23 ondra.novacisko.cz
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
No lokalizaci výjimek mám volitelnou. Valná většina výjimek má veřejný statický atribut ukazatel na char, který ve výchozím stavu ukazuje na text anglické hlášky. Dá se přesměrovat.

Lokalizace hlášek pomáhá i našemu helpdesku. Programátor nemůže postihovat všechny chybové stavy adekvátní reakcí aplikace a některé situace vznikají tak málo často, že se je nevyplatí řešit vůbec a nechat je propadnout až někam, kde se zobrazí uživateli. Je pak rozdíl, když uživatel na helpdesk hlásí "Píše mi to, že se nemůže připojit na adresu xxx" než když mi od uživatele přes helpdesk propadne chyba "Cannnoct make connection..." s tím, že ani helpdesk neví, co to znamená.
18.11.2011 14:43 Sten
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Otázka je, jestli ty hardwarové problémy má smysl řešit zamlčováním. SIGSEGV znamená, že máte pravděpodobně v paměti bordel. SIGILL znamená, že máte v paměti bordel nebo aplikace je pro jiný procesor, což je oboje dost špatné. V Linuxu se to běžně řeší tak, že aplikace se odstřelí a, pokud je to něco důležitého (démon), spustí znovu. Lze to řešit i na úrovni vláken (odstřelit jenom to vlákno, které výjimku vyhodilo), ale i tam může být paměť v bůhvíjakém stavu, proto se to moc nedělá. Pokud ale máte snahu udělat to stejně alibisticky jako ve Windows, tak pomocí setjmp nebo manipulací zásobníku (třeba pomocí ptrace) to lze i v Linuxu, ale měl byste sakra vědět, co vlastně děláte, proto to je tak složité. Ale jde to i tam.
18.11.2011 15:38 ondra.novacisko.cz
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Odchytávání HW výjímek v MSVC už také není extra v módě. Microsoft má defaultní nastavení takové, že se odchytávají jen C++ výjimky. To zjednodušuje kód, protože pak není třeba hlídat každou instrukci, ale pouze jen každé volání kódu, který v daném místě není znám, tedy klasicky funkce, nebo metody (přes CALL). Navíc odpadá hlídání konzistence stavu proměnných na zásobníku, protože zatímco HW výjimka může vylítnout uprostřed jakékoliv změny jakékoliv proměnné, C++ výjimka by měla zanechat proměnnou v konzistentním stavu.
16.11.2011 13:04 ondra.novacisko.cz
Rozbalit Rozbalit vše V jednom případě používám výjimky k jiným učelům
Odpovědět | Sbalit | Link | Blokovat | Admin
Doteď jsem nepřišel na způsob, jak provést cast z potomka na předka za předpokladu, že potomek se ukrývá za nějakým virtuálním rozhraní, který je schopný poskytnout maximálně void * a typeinfo.

něco jako dynamic_cast<typeionfo>(). Pokud rozhraní disponuje funkcí throwAsPtr(), kdy vyhodí předmětný pointer jako výjimku, jsem schopen ji odchytit předkem. Jsem maximálně schopen porobna typeid s tím, co očekávám a udělat reinterpret_cast<> toho pointer.
IAnyIfc *anyobj=new AnyObj<Potomek>(foo);

try {
     anyobj->throwAsPtr();
} catch (Predek *bar) {
    //převedeno z potomka na předka
} catch (...) {
   //není kompatibilní
}
Pokud by někdo věděl, jak udělat dynamic_cast podle typeinfo, byl bych mu vděčný. V MSVC jsem našel jednu neveřejnou funkci, která to dělá, ale pak to není platformovně nezávislé. Má prototyp zhruba tento:
   void *dynamicCastFn(void *src, const typeinfo &from, const typeinfo &to);
16.11.2011 13:13 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: V jednom případě používám výjimky k jiným učelům
Uvědomte si laskavě, že typ A může být třeba int v modulu 1, a class djkjlk v modulu 2.

Typový systém C++ je daný v modulu, v jiném se pod stejným názvem může skrývat zcela jiný typ.

Proto se s tímto moc nenarába.
16.11.2011 18:13 Sten
Rozbalit Rozbalit vše Re: V jednom případě používám výjimky k jiným učelům
Pokud budete mít ve dvou modulech slinkovaných dohromady typ, který se v každém jmenuje stejně, ale je úplně jiný, tak to stejně spadne, protože linker použije vtable jenom z jednoho modulu pro oba dva (pokud to teda není windowsí DLL, ale to je zvláštní případ).
19.11.2011 13:11 Sten
Rozbalit Rozbalit vše Re: V jednom případě používám výjimky k jiným učelům
V GCC a Clangu existuje funkce:
void* __dynamic_cast(void *what, // objekt, který chcete castovat
                                   const __cxxabi1::__class_type_info *from, // třída, pod kterou ten objekt vystupuje teď
                                   const __cxxabi1::__class_type_info *to, // třída, pod kterou chcete, aby ten objekt vystupoval
                                   int hint); // nápověda, pro full scan použijte -1
Tahle funkce vrátí buď pointer na objekt vystupující pod požadovanou třídou (může, ale nemusí být stejný s what) nebo nullptr, pokud to nejde převést. Trochu problém může být dostat se k class type info (nezkoumal jsem to, ale je to skryté někde ve vtable).

Pokud vám stačí konverze od potomka na předka, můžete rovnou použít virtuální metodu std::typeinfo pro castování výjimek
bool std::typeinfo::__do_catch(const std::typeinfo *target, // typeinfo třídy, pod kterou chcete, aby ten objekt vystupoval
                                                 void **what, // pointer na pointer na objekt, který chcete castovat (může se změnit)
                                                 unisgned outer) const; // Indikuje počet vnějších ukazatelů a jejich kvalifikace, podle zdrojáků by tam zřejmě měla být 1 nebo 3
19.11.2011 16:39 ondra.novacisko.cz
Rozbalit Rozbalit vše Re: V jednom případě používám výjimky k jiným učelům
Stene diky, staci z potomka na predka, tak jak je zvykem u standardnich konverzi ukazatelu. Zejmena u kontejneru s rozhranim ktery se konstruuji jako instance sablony.

Predpokladam, ze to neni standarizovane. Zkusim to poresit rozdelenim podle platforem s tim, ze fallback by byl pres vyjimku.
20.11.2011 15:48 Sten
Rozbalit Rozbalit vše Re: V jednom případě používám výjimky k jiným učelům
Standardní to není, je to GCC extenze (začíná to dvěma podtržítky).
16.11.2011 13:33 __dark__
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
Odpovědět | Sbalit | Link | Blokovat | Admin
Napsat C++ do titulku v blogu? To byla jen otázka času - 12:35 :-)
16.11.2011 13:33 __dark__
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
oprava: 12:25 :)
David Watzke avatar 16.11.2011 13:45 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions
:-D
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
16.11.2011 14:33 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Malý benchmark C++ exceptions

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.