C++ a výjimka v destruktoru

Tomáš Marný

Re:C++ a výjimka v destruktoru
« Odpověď #165 kdy: 11. 02. 2014, 23:10:03 »
Ještě bych uvedl jednu dobrou věc na výjimkách obecně. Od té doby, co je používám jako výhradní způsob hlídání chyb mi odpadla jakákoliv práce s vytvářením systémů chybových kódů
...
Zpět na začátek. Hlavně jsem se zbavil definování tisíců chybových kódů a hlídání toho, zda někde nekolidují. Každá knihovna měla vlastní kódy. Díky výjimkám je každá chyba přesně specifikována a zařazena do kategorie. Uvnitř aplikace létají výjimky a na vnějším rozhraní... pokud si to zadavatel přeje ... mám každé výjimkové třídě přidělen nějaký unikátní kód. A protože se to zpravidla řeší na jednom místě, není problém udržet ten seznam kódů bez kolizí.

Výjimky jsou jako záchranné sítě: umožňují vám dělat prasárny na laně nad propastí, neboť víte, že si přitom nezlomíte vaz, maximálně do nich spadnete. Jenže existují oblasti programování, kde si prostě nemůžete dovolit spadnout za žádnou cenu (resp. ta cena je velmi vysoká). Tam jsou vám všechny ty výjimky na nic, protože hrabat se z těch sítí zpátky na místo, odkud jste do nich slítli, je dost náročné.
Vyhazovat výjimky z destruktorů je jako připouštět, že i tu síť jste v zápalu svého prasení ukotvili jen prasecky. Říkejte si, co chcete, ale to už je oberprasárna.

Zpracovávat chybový stav jinde, v jiném kontextu, než kde nastal, je prasárna. Jak už tu padlo, principiálně totiž žádný chybový stav vlastně neexistuje. Je to prostě jen jeden z možných stavů a tedy neexistuje žádný rozumný důvod, proč kvůli němu skákat někam mimo kontext. To už výjimky můžete rovnou použít k předávání návratových hodnot. Výjimku bych chápal tradičně, tj. jako stav, s nímž návrh nepočítal - výjimečný stav, který je třeba ošetřit zvláštním způsobem.

Čím jsem starší tím větší mám pocit, že výjimky nejsou ničím jiným, než jen dalším vynálezem, kterým přiblížit programování nižším primátům. A jak to tak u takových vynálezů chodí, i výjimky fungují na principu, že z jednoduchých věcí dělají primitivní, a z obtížných ku..vsky zamotané. Ta předřečníkova adorace výjimek mi připadá, jako když projektant města vysvětluje, že když jdete po ulici a spadnete do nezadeklovaného kanálu, kterých tam nechal rozeseto mraky, tak výjimky způsoběj, že tam za vámi zahučí i taška a kočárek s dítětem a budete-li mít štěstí a přitom shazování toho kočárku dotyčný shazovatel sám nezahučí do nějakého kanálu, tak se postupně přes systém stok a výpustí můžete dostat zpátky na tu ulici, kde jste spadli. Ušetří se tak za dekly na kanály a to se vyplatí!

Žádné výjimky neudělají program spolehlivějším, ani - ač se to tak na první pohled může zdát - přehlednějším. Spíš naopak. Receptem na robustnost je praxe vývojáře a 3 věci: 1) testování (unit), 2) testování (alfa), 3) testování (beta). Ale můj pohled je dán oborem, v němž celý život působím, tj. embedded aplikace a průmyslové a telekomunikační systémy, kde up-timy jsou spíše roky než měsíce a každý pád stojí peníze - nejen pomyslně, ale reálné peníze, o něž se s vámi klient bude ochoten soudit. To není jako práce s buzolou, děti.


Re:C++ a výjimka v destruktoru
« Odpověď #166 kdy: 11. 02. 2014, 23:59:27 »
Jenže existují oblasti programování, kde si prostě nemůžete dovolit spadnout za žádnou cenu (resp. ta cena je velmi vysoká). Tam jsou vám všechny ty výjimky na nic, protože hrabat se z těch sítí zpátky na místo, odkud jste do nich slítli, je dost náročné.
Výjimka != pád

Prosím naučte se to rozlišovat. Dokonce synchronní výjimky jsou prostě jinou cestou návratu (ten návrat je řízený). Tzv. asynchroní výjimky (výjimka může vzniknout kdekoliv, třeba v signal handleru) já nepoužívám a nikdy nebudu. Výjimka je prostě jen způsob, jak opustit funkci jinudy. Je to něco jiný typ returnu. Nic víc.

Zpracovávat chybový stav jinde, v jiném kontextu, než kde nastal, je prasárna. Jak už tu padlo, principiálně totiž žádný chybový stav vlastně neexistuje. Je to prostě jen jeden z možných stavů a tedy neexistuje žádný rozumný důvod, proč kvůli němu skákat někam mimo kontext.
Vy musíte být geniální programátor, že jste schopen ve svém programu podchytit všechny chybové stavy? Jen si vemte, kolik chybových stavů mají všechna systémová volání, které ve svých programech používáte. Opravdu jste schopen všechny tyhle stavy ošetřit. Na všech úrovních (!)?. A máte jistotu, že to někdo ošetřuje nad vámi (ve hierarchii callstacku)?

To už výjimky můžete rovnou použít k předávání návratových hodnot.
To teda nemůžete. To byste byl teprve prase. Výjimky ani nejsou dělané na takovou věc. Už jen optimalizace kódu se provádí na standardní běh, zatímco zpracování výjimky bývá často velice pomalé (při porovnání s běžným chodem). Naopak, když výjmky nepoužijete a ošetřujete chybové stavy každého volání, program v normálním běhu moc optimální nebude. Každý if znamená jeden odhadnutý skok, který se nemusí vždy povést správně odhadnout a procesor se vám tam zastaví na vyprazdňování fronty. Výjimky tímto netrpí.

JSH

Re:C++ a výjimka v destruktoru
« Odpověď #167 kdy: 12. 02. 2014, 09:46:12 »
Vy musíte být geniální programátor, že jste schopen ve svém programu podchytit všechny chybové stavy? Jen si vemte, kolik chybových stavů mají všechna systémová volání, které ve svých programech používáte. Opravdu jste schopen všechny tyhle stavy ošetřit. Na všech úrovních (!)?. A máte jistotu, že to někdo ošetřuje nad vámi (ve hierarchii callstacku)?
Ošetřit všechny chybové stavy přece není o genialitě, ale o důslednosti. Prostě si navrhnu nějaké rozhraní a při implementaci kouknu do dokumentace na všechno co volám a ošetřuju všechny možné běžné i vzácné stavy. Všechno s čím se dokážu vypořádat na fleku se vypořádám tam. To, co nedám, předám ven. V některých případech to znamená i úpravy rozhraní. Tohle je postup, který nezávisí na tom, jestli se používají výjimky nebo chybové kódy.

Pokud používám chybové kódy, tak moje rozhraní musí předat ven všechny chyby, se kterými se nedokážu vypořádat uvnitř.
Pokud používám výjimky, tak musím minimálně v rozhraní zdokumentovat všechno, co může vyletět z funkcí, které volám uvnitř. Případně můžu ty výjimky vyhozené uvnitř vylepšit nebo konvertovat na něco, co bude venku dávat větší smysl.
O tom, jestli je to víc práce s kódy nebo s výjimkami se dá diskutovat. Ale ta stěžejní část, kdy musím kouknout do manuálu a všechny možné chyby promyslet, je u obou přístupů úplně stejná. Zbytek už je vlastně jen mechanická práce.

randolf

Re:C++ a výjimka v destruktoru
« Odpověď #168 kdy: 12. 02. 2014, 09:57:45 »
Zajimave videt, jak se "high availability" da pojmout ruzne. U nas to znamena nasledujici:
- Zadna dynamicka alokace pameti. Nikdy.

To asi porovnáváme neporovnatelné. Věřte mi nebo ne, ale moje knihovny v současném návrhu (i s výjimkami) se například vůbec nedají použít v Arduinu. A to ani kdybych ty výjimky nějak vyházel. Prostě tam se programuje naprosto jinak a jen díky tomu, že to nedělám denně, nemám na to vytvořené žádné kopyto (konečně o kopytech to celé je, záleží kde a co šijete)
Ale zajiste, ja reagoval pouze na Belzebuba, ne na Vas prispevek. Trosku off-topic, uznavam.

randolf

Re:C++ a výjimka v destruktoru
« Odpověď #169 kdy: 12. 02. 2014, 10:04:37 »
Ještě bych uvedl jednu dobrou věc na výjimkách obecně. Od té doby, co je používám jako výhradní způsob hlídání chyb mi odpadla jakákoliv práce s vytvářením systémů chybových kódů
...
Zpět na začátek. Hlavně jsem se zbavil definování tisíců chybových kódů a hlídání toho, zda někde nekolidují. Každá knihovna měla vlastní kódy. Díky výjimkám je každá chyba přesně specifikována a zařazena do kategorie. Uvnitř aplikace létají výjimky a na vnějším rozhraní... pokud si to zadavatel přeje ... mám každé výjimkové třídě přidělen nějaký unikátní kód. A protože se to zpravidla řeší na jednom místě, není problém udržet ten seznam kódů bez kolizí.

Výjimky jsou jako záchranné sítě: umožňují vám dělat prasárny na laně nad propastí, neboť víte, že si přitom nezlomíte vaz, maximálně do nich spadnete. Jenže existují oblasti programování, kde si prostě nemůžete dovolit spadnout za žádnou cenu (resp. ta cena je velmi vysoká). Tam jsou vám všechny ty výjimky na nic, protože hrabat se z těch sítí zpátky na místo, odkud jste do nich slítli, je dost náročné.
Vyhazovat výjimky z destruktorů je jako připouštět, že i tu síť jste v zápalu svého prasení ukotvili jen prasecky. Říkejte si, co chcete, ale to už je oberprasárna.

Zpracovávat chybový stav jinde, v jiném kontextu, než kde nastal, je prasárna. Jak už tu padlo, principiálně totiž žádný chybový stav vlastně neexistuje. Je to prostě jen jeden z možných stavů a tedy neexistuje žádný rozumný důvod, proč kvůli němu skákat někam mimo kontext. To už výjimky můžete rovnou použít k předávání návratových hodnot. Výjimku bych chápal tradičně, tj. jako stav, s nímž návrh nepočítal - výjimečný stav, který je třeba ošetřit zvláštním způsobem.

Čím jsem starší tím větší mám pocit, že výjimky nejsou ničím jiným, než jen dalším vynálezem, kterým přiblížit programování nižším primátům. A jak to tak u takových vynálezů chodí, i výjimky fungují na principu, že z jednoduchých věcí dělají primitivní, a z obtížných ku..vsky zamotané. Ta předřečníkova adorace výjimek mi připadá, jako když projektant města vysvětluje, že když jdete po ulici a spadnete do nezadeklovaného kanálu, kterých tam nechal rozeseto mraky, tak výjimky způsoběj, že tam za vámi zahučí i taška a kočárek s dítětem a budete-li mít štěstí a přitom shazování toho kočárku dotyčný shazovatel sám nezahučí do nějakého kanálu, tak se postupně přes systém stok a výpustí můžete dostat zpátky na tu ulici, kde jste spadli. Ušetří se tak za dekly na kanály a to se vyplatí!

Žádné výjimky neudělají program spolehlivějším, ani - ač se to tak na první pohled může zdát - přehlednějším. Spíš naopak. Receptem na robustnost je praxe vývojáře a 3 věci: 1) testování (unit), 2) testování (alfa), 3) testování (beta). Ale můj pohled je dán oborem, v němž celý život působím, tj. embedded aplikace a průmyslové a telekomunikační systémy, kde up-timy jsou spíše roky než měsíce a každý pád stojí peníze - nejen pomyslně, ale reálné peníze, o něž se s vámi klient bude ochoten soudit. To není jako práce s buzolou, děti.

Vpodstate s Vami souhlasim. Predpokladam ovsem, ze pokud by puvodni tazatel chtel delat kod pro takovou aplikaci, tak by vyjimky nepouzil. Pokud je jeho cilem vlastni aplikace pro dejme tomu sledovani poctu vypranych ponozek, je to asi OK, ne? At si je klidne pouzije :)


Re:C++ a výjimka
« Odpověď #170 kdy: 12. 02. 2014, 10:31:00 »
Ošetřit všechny chybové stavy přece není o genialitě, ale o důslednosti. Prostě si navrhnu nějaké rozhraní a při implementaci kouknu do dokumentace na všechno co volám a ošetřuju všechny možné běžné i vzácné stavy. Všechno s čím se dokážu vypořádat na fleku se vypořádám tam. To, co nedám, předám ven. V některých případech to znamená i úpravy rozhraní. Tohle je postup, který nezávisí na tom, jestli se používají výjimky nebo chybové kódy.
No máte a nemáte pravdu. Samozřejmě, že chybové stavy vyplývající z činnosti volaného programu/metody/funkce/whatever by mělo být ošetřeno uvnitř a vypadávat ven tak, jak bylo navrženo. Chybové stavy nějakého stavového automatu jsou stavy toho automatu, ne výjimky (k tomu se výjimky nepoužívají).

Nevím, kolik máte za sebou praxe, ale určitě víte, že člověk málokdy píše konečnou funkcionalitu, která dále nezávisí na jiných neznámých. Jednou neznámou je třeba fungování platformy. Proto jsem se ptal, jestli jsou mezi námi tak geniální nebo důslední programátoři, že jsou schopni ošetřit všechny chybové stavy. Protože považte, kolik chybových stavů má jenom funkce fopen

http://www.root.cz/man/3/fopen/

Druhou neznámou jsou dodané objekty z venku, které mohou neočekávaně selhat. Například callback funkce, handlery všelijakého druhu a podobně. Je třeba mít mechanismus, jak s tím naložit

Pokud používám chybové kódy, tak moje rozhraní musí předat ven všechny chyby, se kterými se nedokážu vypořádat uvnitř.
Jak zajišťujete nekolidování chybových kódů


Pokud používám výjimky, tak musím minimálně v rozhraní zdokumentovat všechno, co může vyletět z funkcí, které volám uvnitř. Případně můžu ty výjimky vyhozené uvnitř vylepšit nebo konvertovat na něco, co bude venku dávat větší smysl.
O tom, jestli je to víc práce s kódy nebo s výjimkami se dá diskutovat. Ale ta stěžejní část, kdy musím kouknout do manuálu a všechny možné chyby promyslet, je u obou přístupů úplně stejná. Zbytek už je vlastně jen mechanická práce.

To je otázkou, zda vnitřní výjimky odchytávat a přebalovat je na nějaké vnější výjimky, které jsem si  pro tento účel vytvořil. Má to několik háčků.
  • Přebalením do jiné výjimky ztrácím zpravidla informace, které často mohou být cenné - z toho důvodu používám po vzoru Javy tzv. Reason. Sice přebalím výjimku, ale původní výjimku vložím k nové výjimce jako reason. Taková výjimka se třeba pak zaloguje: "Exception - unable to open session, because: can't connect service provider, because: can't create connection to localhost:17700" - takováhle výjimka má v sobě hned dva reasony zřetězené za sebou jak byly slepovány když letěly ven - tenhle systém vyžaduje mít propracovaný výjimkový systém
  • Přebalením do jiné výjimky mohu zmást volajícího, za předpokladu, že se mi podaří přebalit výjimku, kterou vyhodil jeho objekt, se kterým se pracovalo - volající očekával, že poletí výjimka z jeho objektu, ale ve skutečnosti letěla jiná výjimka a propadla až na základní úroveň - fail
  • Někdy může být problém zdokumentovat všechny možné výjimky letící ven, když není známo v jakém prostředí bude algoritmus fungovat. Například se vám může stát, že vám někdo podstrčí virtuální filesystem, na kterém létají naprosto odlišné výjimky, než jste zvyklý - (má knihovna má přístup na fs přes rozhraní, které jde přepsat vlastní verzí, aniž by na první pohled bylo poznat, že program nepracuje s fyzickým diskem, nebo s fyzickou sítí, například)


I tady je třeba postupovat opatrně a z rozvahou.



belzebub

Re:C++ a výjimka
« Odpověď #171 kdy: 12. 02. 2014, 14:31:43 »
Ošetřit všechny chybové stavy přece není o genialitě, ale o důslednosti. Prostě si navrhnu nějaké rozhraní a při implementaci kouknu do dokumentace na všechno co volám a ošetřuju všechny možné běžné i vzácné stavy. Všechno s čím se dokážu vypořádat na fleku se vypořádám tam. To, co nedám, předám ven. V některých případech to znamená i úpravy rozhraní. Tohle je postup, který nezávisí na tom, jestli se používají výjimky nebo chybové kódy.
No máte a nemáte pravdu.
Ma pravdu. Tecka.

Nevím, kolik máte za sebou praxe, ale určitě víte, že člověk málokdy píše konečnou funkcionalitu, která dále nezávisí na jiných neznámých. Jednou neznámou je třeba fungování platformy. Proto jsem se ptal, jestli jsou mezi námi tak geniální nebo důslední programátoři, že jsou schopni ošetřit všechny chybové stavy. Protože považte, kolik chybových stavů má jenom funkce fopen

Nemuzu mluvit za JSH, ale za me: neni nutne osetrit vsechny mozne stavy individualne. Zalezi na stavech, ktere jsou pro danou aplikaci relevantni. Pokud aplikace nepotrebuje zadnym zpusobem vedet, proc se nepodarilo soubor otevrit, pak takove osetreni resi pouze 2 stavy: OK/ERROR. To ze "ERROR" v sobe obsahuje bazilion ruznych chyb je v tomto pripade mozne ignorovat. Podstatne je pouze osetrit CELY stavovy prostor - jak detailne uz zavisi na tom, co od aplikace ocekavame.
S timto pristupem neni reseni chyb nijak komplikovane ani s chybovymi kody.

Druhou neznámou jsou dodané objekty z venku, které mohou neočekávaně selhat. Například callback funkce, handlery všelijakého druhu a podobně. Je třeba mít mechanismus, jak s tím naložit
Takove objekty musi mit jasne definovane rozhrani - a tedy zpusob jak zjistit zda selhaly (a opet je jedno jestli nejakym try/catch nebo osetrenim errorcodu). Ve vetsine pripadu staci brat opet pouze 2 stavy - externi objekt selhal, nebo neselhal. Osetreni opet trivialni.

Jak zajišťujete nekolidování chybových kódů
Jak zajistujete iteraci pres seznam? Stejne jako na tuto otazku, odpovedi muze byt mnoho. Co treba:

1) Ja jsem zminoval glib - jeji GError resi nejen nekolidovani (internovani textovych identifikatoru chyby pri jeji definici) ale i hierarchii (plus prilozeni dalsich informaci k chybe, coz jste z me neznamych duvodu pokladal za nejakou vymozenost vyjimek)
2) rucne v jednom enum-u v jednom globalnim hlavickovem souboru pro chyby (idealne automaticky generovanem z nejakeho textaku kde je k chybe doplnen i jeji lokalizovatelny textovy popis)
3) "neresim" - kazdy "modul" (napr. foo.c, foo.h) ma sve errorkody s prefixem "ERROR_FOO_" - jejich skutecna integer hodnota nemusi byt nijak unikatni, protoze selhani modulu "foo" musi resit kod, ktery ho vola a protoze "foo" muze vratit pouze "ERROR_FOO_*" kody, neni zadny duvod pro jejich unikatnost.
4) za domaci ukol si kazdy muze vymyslet sve vlastni reseni :)



To je otázkou, zda vnitřní výjimky odchytávat a přebalovat je na nějaké vnější výjimky, které jsem si  pro tento účel vytvořil. Má to několik háčků.
S tim nesouhlasim. Prebaleni chyby/vyjimky je NUTNE, pokud chci mit rozume rozdelene zodpovednosti objektu/modulu, pokud chci nejake rozumne zapouzdreni a hlavne pokud nezapouzdrim, tak to je naprosto nezadouci zavislost rozhrani meho objektu/modulu na nizsich objektech/modulech, ktera proteka az do nejvyssi urovne.
To je asi jakoby Vam Firefox pri nezdarenem pokusu o otevreni stranky vypsal HTTP odpoved, TCP/IP packety, ethernetove pakety, atd, atd.
Myslim, ze to co povazujete za "hacek" vesmes resi logovani.
Chybovy kod/vyjimka musi programu pouze umoznit se pri chybe vydat "jinou cestou" nez bez chyby. Opet je to o duslednosti a opet je to o spravnem rozdeleni stavoveho prostoru - pokud pouziji vyse zmineny "fopen": budu mit "konfiguracni" objekt, ktery precte a rozparsuje konfiguracni soubor, tak prestoze "fopen" muze vratit mnozstvi chyb, v 99% pripadu bude mit muj "konfiguracni" soubor pouze jeden chybovy stav pro selhavsi "fopen" - neco ve stylu: ERROR_CONFIG_OPEN("Couldn't open configuration file myapp.cfg"). Presny errorcode proc "fopen" selhal neni nutne uvadet. A pokud aplikace VYZADUJE aby se rozlisila napr. chyba s pravy uzivatele, tak se prida tato chyba. Ale je dulezite, aby se konfiguracni objekt zvenku choval jako blackbox s PRESNE definovanym chovanim a chybovymi stavy. Detaily pak lze nalezt v logu.


Pane Novak, nechci Vas nebudu obvinovat z neznalosti, nedostatecnych "1337 skillz", nebo podobne. Ale ja jsem v C delal uz na 3 netrivialnich projektech, a vetsinu Vasich namitek co "nejde" bez vyjimek, jsem mnohokrat a bez vetsich problemu resil.
Ale tim, ze "predpokladate", ze to v C nejde (protoze delate v C++), se stavite presne do te pozice cloveka, ktery neco nezna, nepouziva to, ale je presvedcen ze o tom vse vi a vi proc je to spatne a proc je to co pouziva on lepsi.

Sten

Re:C++ a výjimka
« Odpověď #172 kdy: 12. 02. 2014, 14:54:53 »
Někdy může být problém zdokumentovat všechny možné výjimky letící ven, když není známo v jakém prostředí bude algoritmus fungovat. Například se vám může stát, že vám někdo podstrčí virtuální filesystem, na kterém létají naprosto odlišné výjimky, než jste zvyklý - (má knihovna má přístup na fs přes rozhraní, které jde přepsat vlastní verzí, aniž by na první pohled bylo poznat, že program nepracuje s fyzickým diskem, nebo s fyzickou sítí, například)

Tohle se ale týká i chybových kódů. Není neobvyklé, že některé funkce v libc dnes vracejí i jiné chyby, než byly v dokumentaci v době psaní programu (třeba open na Linuxu vrací navíc oproti POSIXu EWOULDBLOCK). Prostě je potřeba počítat i s tím, že to selže jinak, než je v dokumentaci.

Jak zajistujete iteraci pres seznam? Stejne jako na tuto otazku, odpovedi muze byt mnoho. Co treba:

1) Ja jsem zminoval glib - jeji GError resi nejen nekolidovani (internovani textovych identifikatoru chyby pri jeji definici) ale i hierarchii (plus prilozeni dalsich informaci k chybe, coz jste z me neznamych duvodu pokladal za nejakou vymozenost vyjimek)
2) rucne v jednom enum-u v jednom globalnim hlavickovem souboru pro chyby (idealne automaticky generovanem z nejakeho textaku kde je k chybe doplnen i jeji lokalizovatelny textovy popis)
3) "neresim" - kazdy "modul" (napr. foo.c, foo.h) ma sve errorkody s prefixem "ERROR_FOO_" - jejich skutecna integer hodnota nemusi byt nijak unikatni, protoze selhani modulu "foo" musi resit kod, ktery ho vola a protoze "foo" muze vratit pouze "ERROR_FOO_*" kody, neni zadny duvod pro jejich unikatnost.
4) za domaci ukol si kazdy muze vymyslet sve vlastni reseni :)

Už jsem viděl i řešení, které vracelo const char* se statickým popiskem chyby (NULL pokud nic neselhalo). Přišlo mi to jako v podstatě geniální řešení chybových kódů, které řeší popisky i unikátnost kódů :-)

S tim nesouhlasim. Prebaleni chyby/vyjimky je NUTNE, pokud chci mit rozume rozdelene zodpovednosti objektu/modulu, pokud chci nejake rozumne zapouzdreni a hlavne pokud nezapouzdrim, tak to je naprosto nezadouci zavislost rozhrani meho objektu/modulu na nizsich objektech/modulech, ktera proteka az do nejvyssi urovne.
To je asi jakoby Vam Firefox pri nezdarenem pokusu o otevreni stranky vypsal HTTP odpoved, TCP/IP packety, ethernetove pakety, atd, atd.
Myslim, ze to co povazujete za "hacek" vesmes resi logovani.
Chybovy kod/vyjimka musi programu pouze umoznit se pri chybe vydat "jinou cestou" nez bez chyby. Opet je to o duslednosti a opet je to o spravnem rozdeleni stavoveho prostoru - pokud pouziji vyse zmineny "fopen": budu mit "konfiguracni" objekt, ktery precte a rozparsuje konfiguracni soubor, tak prestoze "fopen" muze vratit mnozstvi chyb, v 99% pripadu bude mit muj "konfiguracni" soubor pouze jeden chybovy stav pro selhavsi "fopen" - neco ve stylu: ERROR_CONFIG_OPEN("Couldn't open configuration file myapp.cfg"). Presny errorcode proc "fopen" selhal neni nutne uvadet. A pokud aplikace VYZADUJE aby se rozlisila napr. chyba s pravy uzivatele, tak se prida tato chyba. Ale je dulezite, aby se konfiguracni objekt zvenku choval jako blackbox s PRESNE definovanym chovanim a chybovymi stavy. Detaily pak lze nalezt v logu.

Tohle má ale jednu velkou výjimku (pun intended :) ): callbacky. V případě, kdy dojde k chybě v callbacku, tak přebalením zabráníte volajícímu poznat, co se stalo, a nepřebalením zase rozbijete contract. I když, u výjimek to jde zabalit jako CallbackFailed a původní výjimku vložit do ní a u error codů jde vyhradit nějaký rozsah pro chyby callbacků.

Re:C++ a výjimka
« Odpověď #173 kdy: 12. 02. 2014, 15:40:31 »
pouze 2 stavy: OK/ERROR. To ze "ERROR" v sobe obsahuje bazilion ruznych chyb je v tomto pripade mozne ignorovat. Podstatne je pouze osetrit CELY stavovy prostor - jak detailne uz zavisi na tom, co od aplikace ocekavame.
S timto pristupem neni reseni chyb nijak komplikovane ani s chybovymi kody.
Znám spoustu programů, které, když se jim něco nelíbí, tak napíšou "ERROR" a skončí.

Takove objekty musi mit jasne definovane rozhrani - a tedy zpusob jak zjistit zda selhaly (a opet je jedno jestli nejakym try/catch nebo osetrenim errorcodu). Ve vetsine pripadu staci brat opet pouze 2 stavy - externi objekt selhal, nebo neselhal. Osetreni opet trivialni.

Samozřejmě, že je ošetření trivální. ERROR  ;D

1) Ja jsem zminoval glib - jeji GError resi nejen nekolidovani (internovani textovych identifikatoru chyby pri jeji definici) ale i hierarchii (plus prilozeni dalsich informaci k chybe, coz jste z me neznamych duvodu pokladal za nejakou vymozenost vyjimek)
Vidíte! A ony přesně výjimky takhle fungují. Jediný co mají navíc je to, že nemusíte psát kolem volání IFy
Kód: [Vybrat]
if (!foo()) return 0;
if (!bar()) return 0;
if (!fee()) return 0;
pokud nastane chyba ve foo, tak vyhozená výjimka jedná ve stejném duchu, jako výše uvedený zápis, udělá return s nějakým chybovým příznakem, aby nadřazená funkce věděla, že nastala chyba. Vám ušetří psaní. Informace o výjimce se drží v nějaké statické TLS proměnné, odkud se pak vyzvedávají v handleru.

Proč teda vy lidi máte takovou averzi vůči výjimkám, když jde jen o syntax-suggar?

Výhodou výjimek je to, že fungují stejně třeba i ve Windows, kde není glib a ani GError
2) rucne v jednom enum-u v jednom globalnim hlavickovem souboru pro chyby (idealne automaticky generovanem z nejakeho textaku kde je k chybe doplnen i jeji lokalizovatelny textovy popis)
Globální hlavičkový soubor... vy asi nepíšete knihovny?

3) "neresim" - kazdy "modul" (napr. foo.c, foo.h) ma sve errorkody s prefixem "ERROR_FOO_" - jejich skutecna integer hodnota nemusi byt nijak unikatni, protoze selhani modulu "foo" musi resit kod, ktery ho vola a protoze "foo" muze vratit pouze "ERROR_FOO_*" kody, neni zadny duvod pro jejich unikatnost.
A z modulu FOO vyhodíte chybu do modulu BAR tak že nadefinujete proměnnou ERROR_BAR_ERROR_IN_FOO a tu zareportujete ven. Co se vlastně ve FOO stalo, to už se nikdo nedozví. Když to neuděláte vy, tak to udělá váš nějaký méně zdatný kolega. Nebo to udělá proto, že mu na vývoj modulu nadřizený přidělil málo času (pak je 1000x lepší, když vylítne výjimka přímoz FOO, než když ji někdo zahodí a vyhodí obecnou chybu)


To je asi jakoby Vam Firefox pri nezdarenem pokusu o otevreni stranky vypsal HTTP odpoved, TCP/IP packety, ethernetove pakety, atd, atd.
Co myslíte, jak mi je, když mi Firefox napíše, že "Stránka se nedá zobrazit" (aby třeba k tomu dodal, že DNS jméno neexistuje, nebo že selhalo spojení, což mi třeba napoví, že jméno mám správně, ale blbec jsem si nohou vykopnul kabel z ethernetu)

pouze jeden chybovy stav pro selhavsi "fopen" - neco ve stylu: ERROR_CONFIG_OPEN("Couldn't open configuration file myapp.cfg"). Presny errorcode proc "fopen" selhal neni nutne uvadet.

Opět jeden příklad z praxe. Neustále to hlásilo, že to nemůže otevřít nějaké datové soubory. Dokonce někoho chytrého napadlo, že by bylo dobré uživateli napovědět, co má dělat. Ať si prý zkontroluje, zda tam ty soubory jsou. No byly tam, ale program stále tvrdil, že tam nejsou. Až po podrobném prozkoumání problému pomocí strace se ukázalo, důvodem, proč to nejde je chyba "Access Denied". Po úpravě přístupových práv k těm souborům se to už rozběhlo. Jistě, že to někoho mohlo napadnout předtím, ale nenapadlo... celé odpoledne zabyté jen tím, že autor programu měl podobný názor jako vy.

Pane Novak, nechci Vas nebudu obvinovat z neznalosti, nedostatecnych "1337 skillz", nebo podobne. Ale ja jsem v C delal uz na 3 netrivialnich projektech, a vetsinu Vasich namitek co "nejde" bez vyjimek, jsem mnohokrat a bez vetsich problemu resil.
Ale tim, ze "predpokladate", ze to v C nejde (protoze delate v C++), se stavite presne do te pozice cloveka, ktery neco nezna, nepouziva to, ale je presvedcen ze o tom vse vi a vi proc je to spatne a proc je to co pouziva on lepsi.

Jen 3?  ;D  ;D  ;D  ;D

belzebub

Re:C++ a výjimka
« Odpověď #174 kdy: 12. 02. 2014, 16:58:10 »
pouze 2 stavy: OK/ERROR. To ze "ERROR" v sobe obsahuje bazilion ruznych chyb je v tomto pripade mozne ignorovat. Podstatne je pouze osetrit CELY stavovy prostor - jak detailne uz zavisi na tom, co od aplikace ocekavame.
S timto pristupem neni reseni chyb nijak komplikovane ani s chybovymi kody.
Znám spoustu programů, které, když se jim něco nelíbí, tak napíšou "ERROR" a skončí.
Ja znam spousti lidi co maji bradavici na nose. Jak to souvisi s vyjimkami a errorkody? Nijak. Stejne jako Vase vyjadreni ze nejake programy co znate napisi "ERROR".

Takove objekty musi mit jasne definovane rozhrani - a tedy zpusob jak zjistit zda selhaly (a opet je jedno jestli nejakym try/catch nebo osetrenim errorcodu). Ve vetsine pripadu staci brat opet pouze 2 stavy - externi objekt selhal, nebo neselhal. Osetreni opet trivialni.
Samozřejmě, že je ošetření trivální. ERROR  ;D
Ne, osetreni neni "ERROR", ale nekolik "nadstavu", ktere pokryvaji mnozinu VSECH stavu. Ano, je mozne mit pouze dva "nadstavy": OK a ERROR.

Vidíte! A ony přesně výjimky takhle fungují. Jediný co mají navíc je to, že nemusíte psát kolem volání IFy
Pane Novak. Ja VIM jak funguji vyjimky. Chapu ze jste podeziravy, ale dokazete pripustit, ze chapu vyjimky v C++, v Jave, v C#, v Pythonu, delal jsem i s "vyjimkami" v CLOS, s Exception monad-ami v haskellu.
Chapu koncept vyjimek v C++. Zkuste predstirat, ze mi verite.

Proč teda vy lidi máte takovou averzi vůči výjimkám, když jde jen o syntax-suggar?
"My lidi" - to nevim koho myslite. Ale ja, clovek, k tomu mam averzi proto, ze vyjimky (v C++!! a podobnych jazycich - nemam nic proti CLOS vyjimkam nebo "vyjimkam" realizovanym pres monady v haskellu) jsou syntax-suggar, ktery usnadnuje psani spatne osetreni chybovych stavu. Tj. umoznuje psat kod, ktery VYPADA, ze je na prvni pohled cisty, krasny, jasny, ale ve skutecnosti muze byt semeniste prasaren, segfaultu a jinych radosti.

Pro ujasneni - netvrdim, ze vyjimky jsou NAPROSTO SPATNE - tvrdim, ze SPRAVNE osetrovani chybovych stavu pouzivanim vyjimek v C++ je MNOHEM SLOZITEJSI, NEZ TO VYPADA, a proto ho vetsina lidi udela SPATNE.


Výhodou výjimek je to, že fungují stejně třeba i ve Windows, kde není glib a ani GError
Prosim, budte tak laskav a neco si o glib zjistete. Jedna z hlavnich vyhod pro glib (a proc ji pouzivame), je to, ze je EXTREMNE dobre prenositelna mezi platformami - tj. na windows bezi uplne stejne dobre jako na linuxu. Je to normalni C knihovna. Dokonce nepotrebuje ani gcc.
Tj. nemate pravdu, glib s GErrorem je VSUDE, kde je C kompilator.

2) rucne v jednom enum-u v jednom globalnim hlavickovem souboru pro chyby (idealne automaticky generovanem z nejakeho textaku kde je k chybe doplnen i jeji lokalizovatelny textovy popis)
Globální hlavičkový soubor... vy asi nepíšete knihovny?
Jisteze pisi. Soubor je "globalni v ramci jedne nebo vice knihoven", stejne jako je "globalni" treba errno.h.
Opet bych Vas poprosil, abyste zkusil argumentovat fakty, a ne neustalym naznacovanim ze "nic neumim a nicemu nerozumim".

3) "neresim" - kazdy "modul" (napr. foo.c, foo.h) ma sve errorkody s prefixem "ERROR_FOO_" - jejich skutecna integer hodnota nemusi byt nijak unikatni, protoze selhani modulu "foo" musi resit kod, ktery ho vola a protoze "foo" muze vratit pouze "ERROR_FOO_*" kody, neni zadny duvod pro jejich unikatnost.
A z modulu FOO vyhodíte chybu do modulu BAR tak že nadefinujete proměnnou ERROR_BAR_ERROR_IN_FOO a tu zareportujete ven. Co se vlastně ve FOO stalo, to už se nikdo nedozví. Když to neuděláte vy, tak to udělá váš nějaký méně zdatný kolega. Nebo to udělá proto, že mu na vývoj modulu nadřizený přidělil málo času (pak je 1000x lepší, když vylítne výjimka přímoz FOO, než když ji někdo zahodí a vyhodí obecnou chybu)
V BAR zavolam FOO a ten vrati ERROR_FOO_*, tato chyba se zaloguje (tj. co se stalo ve FOO se dozvi kdokoliv, kdo se koukne do logu) a na zaklade hodnoty chyby vyberu co dal delat, a protoze, jak jsem psal o zabalovani chyb/vyjimek, vratim chybu, ktera ma VYZNAM v kontextu BAR. tj. tam kde puvodni chyba byla ERROR_FOO_DISK_FULL muzu vratit treba ERROR_BAR_STORAGE_FULL..
Mimochodem neco podobneho jsem pouzil jen nekolikrat, vzdy u dost malych knihoven, kde by pouziti glib a GError byla zbytecne "velka" zavislost. Klicove slovo je "dost malych". Pokud je kod maly, dostatecne jasne definovano co ma delat, neni toto schema (i kdybych pripustil vase ERROR_BAR_IN_FOO "retezeni") nijak problematicke.

To je asi jakoby Vam Firefox pri nezdarenem pokusu o otevreni stranky vypsal HTTP odpoved, TCP/IP packety, ethernetove pakety, atd, atd.
Co myslíte, jak mi je, když mi Firefox napíše, že "Stránka se nedá zobrazit" (aby třeba k tomu dodal, že DNS jméno neexistuje, nebo že selhalo spojení, což mi třeba napoví, že jméno mám správně, ale blbec jsem si nohou vykopnul kabel z ethernetu)
Ano, firefox Vam napovi, ale pouze z VELMI OMEZENEHO mnozstvi chybovych stavu - coz je presne to o cem mluvim - firefox Vam nenahlasi KAZDOU MOZNOU CHYBU - pouze nekolik, ktere si podle vyvojaru zaslouzi vlastni "kategorii". Pro vsechno ostatni bude "selhalo spojeni". Coz, jak rikate "napovi", nicmene se jedna o to, o cem mluvim ja - "zabaleni" vyjimky - firefox Vam nepovi o tom, jaky errorcode vratil "socket", nerekne vam na jake pozici doslo ke korupci paketu. Napise "selhalo spojeni", protoze to je ta "zabalena" chyba/vyjimka. Natoz aby Vam rekl ze jste blbec a ze jste si vykopnul kabel.
Coz souvisi s tim cemu se obcas rika "leaky abstraction" - proste kazda vyssi vrstva je ve vetsine pripadu nucena provest nejake "zobecneni" urcitych chybovych stavu pod jednu "strechu". Pak NENI mozne bez dalsich nastroju zjistit, kde k chybe doslo. To je ale normalni, a je to v poradku. Firefox nema slouzit jako diagnostika site. Na to jsou jine nastroje.

pouze jeden chybovy stav pro selhavsi "fopen" - neco ve stylu: ERROR_CONFIG_OPEN("Couldn't open configuration file myapp.cfg"). Presny errorcode proc "fopen" selhal neni nutne uvadet.
Opět jeden příklad z praxe. Neustále to hlásilo, že to nemůže otevřít nějaké datové soubory. Dokonce někoho chytrého napadlo, že by bylo dobré uživateli napovědět, co má dělat. Ať si prý zkontroluje, zda tam ty soubory jsou. No byly tam, ale program stále tvrdil, že tam nejsou. Až po podrobném prozkoumání problému pomocí strace se ukázalo, důvodem, proč to nejde je chyba "Access Denied". Po úpravě přístupových práv k těm souborům se to už rozběhlo. Jistě, že to někoho mohlo napadnout předtím, ale nenapadlo... celé odpoledne zabyté jen tím, že autor programu měl podobný názor jako vy.
NE, pletete si priklad s pristupem.

K prikladu - ano, to je bezne, a napr. me by nenapadlo "podrobne zkoumat problem pomoci strace", protoze vim ze duvodu, proc NEJDE OTEVRIT soubor, je nekolik, a chybejici prava je asi druhy, ktery bych zjistoval

K pristupu:
Ja jsem explicitne napsal (v te casti, kterou jste se rozhodl necitovat), ze pokud MA SMYSL DALSI CHYBOVY STAV Z HLEDISKA APLIKACE, tak se samozrejme prida i dalsi chybovy stav. Vase argumentace je zalozena na tom, ze jsem v prikladu, ukazujicim redukci vsech moznych stavu na STAVY VYZNAMNE PRO APLIKACI, pouzil ZAMERNE ZJEDNODUSENI.
Protoze jinak se jedne presne o to same, jako priklad s Firefoxem a vypadlym kabelem. Firefox Vam TAKE nerekne, ze vypadl kabel (i kdyz eth karta to vi!!), ale ze nemuze navazat spojeni.


Pane Novak, nechci Vas nebudu obvinovat z neznalosti, nedostatecnych "1337 skillz", nebo podobne. Ale ja jsem v C delal uz na 3 netrivialnich projektech, a vetsinu Vasich namitek co "nejde" bez vyjimek, jsem mnohokrat a bez vetsich problemu resil.
Ale tim, ze "predpokladate", ze to v C nejde (protoze delate v C++), se stavite presne do te pozice cloveka, ktery neco nezna, nepouziva to, ale je presvedcen ze o tom vse vi a vi proc je to spatne a proc je to co pouziva on lepsi.
Jen 3?  ;D  ;D  ;D  ;D
Ano, jen 3. Projekt se navrhne, napise, odladi, spusti a udrzuje. Klicove slovicko, ktere jste zjevne zamerne ignoroval je "netrivialni". Napiste mi prosim, na kolika netrivialnich projektech (rekneme nad 50 000 radek), v C (ne C++) jste se podilel Vy.

Re:C++ a výjimka
« Odpověď #175 kdy: 12. 02. 2014, 17:19:02 »
Výhodou výjimek je to, že fungují stejně třeba i ve Windows, kde není glib a ani GError
Prosim, budte tak laskav a neco si o glib zjistete. Jedna z hlavnich vyhod pro glib (a proc ji pouzivame), je to, ze je EXTREMNE dobre prenositelna mezi platformami - tj. na windows bezi uplne stejne dobre jako na linuxu. Je to normalni C knihovna. Dokonce nepotrebuje ani gcc.
Tj. nemate pravdu, glib s GErrorem je VSUDE, kde je C kompilator.

Prosím oddělme dvě věci. Jednou je Windows svět (se svým WinAPI, GDI, MFC, COM+ a jinými 3,14covinami), a podruhé je linuxový svět přeportovaný do Windows. To druhé vypadá jak pěst na voko, sorry.

Já už nebudu natahovat diskuzi na téma výjimky, nikam to nevede. Každý máme svou pravdu. Já bych se k systému bez výjimek nevracel ani omylem. Dokud tedy nemusím. Následující dva kódy ukazují, proč tomu tak je. Jedná se o program "hello world" napsaný pod mým systémem WebGUI (časem to bude openSource, možná na to bude článek - ale to je v celku jedno). První je v C++, kde se chyby ošetřují výjimkou. Druhý je napsaný v C, s patřičným ošetřením všech chyb.

Kód: [Vybrat]
#include <stdlib.h>
#include <memory>
#include <string.h>
#include "webgui/IClient.h"


static const char *hellotext = "Hello World";



int main(int argc, char **argv) {

const char *webguiaddr = getenv("WEBGUI");
if (webguiaddr == 0) {
fprintf(stderr, "WEBGUI env variable is not defined\n");
return 1;
}

try {
std::auto_ptr<webgui::IClient> client(webgui::createClient());
client->connect(webguiaddr);
client->createWindow(client->getBaseUrl());
std::auto_ptr<webgui::IRequest> r(client->getRequest(30000));
if (r.get() == 0) {
fprintf(stderr,"Timeout waiting on request\n");
} else {
r->setHeader("Content-Type","text/plain");
r->write(hellotext,strlen(hellotext));
r->closeOutput();
}

} catch (std::exception &e) {
fprintf(stderr, "%s\n", e.what());
}



}
Kód: [Vybrat]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "webgui/webgui_c.h"


static const char *hellotext = "Hello World";

static int showError() {
fprintf(stderr,"Exception: %s\n",webgui_getLastErrorStr());
webgui_clearError();
return 100;
}


int main(int argc, char **argv) {

WEBGUI_STR baseUrl;
WEBGUI_CLIENT client;
WEBGUI_REQUEST r;
int err = 0;
const char *webguiaddr = getenv("WEBGUI");
//if doesnt exist, report error
if (webguiaddr == 0) {
fprintf(stderr, "WEBGUI env variable is not defined\n");
return 1;
}

client = webgui_client_create();
do {
if (!webgui_connect(client,webguiaddr)) break;
if (!webgui_getBaseUrl(client,&baseUrl)) break;
if (!webgui_createWindow(client,&baseUrl)) break;
r = webgui_getRequest(client,30000);
if (r == 0) {
   fprintf(stderr,"Timeout waiting on request\n");
} else {
do {
if (!webgui_setHeader(r,"Conten-Type","text/plain")) break;
if (!webgui_write(r,hellotext,strlen(hellotext))) break;
if (!webgui_closeOutput(r))  break;
} while (0);
if (webgui_getLastErrorStr() != 0) {
err = showError();
}
webgui_closeRequest(r);
}
} while (0);

if (webgui_getLastErrorStr() != 0)
err = showError();

webgui_client_destroy(client);
return err;



}


Pár poznámek k tomu co není vidět. C rozhraní je samozřejmě wraperem původního C++. Výjimky se tedy tady maskují ve funkci webgui_getLastErrorStr(). což je asi jediný rozumný způsob, jak přistupovat k chybě. Je pochopitelné, že proměnná, která drží chybu musí být vnitřně deklarovaná přes __thread (kdyby více vláken). Nemám tu chybové kódy, protože v celké knihovně není jediný (ale mám tam webgui_getLastErrorType(), která vrací řetězec identifikující typ chyby.

Já nevím, osobně mě to přijde jako hádat se, zda v HTML používat nebo nepoužívat tabulkový design.

Re:C++ a výjimka
« Odpověď #176 kdy: 12. 02. 2014, 17:25:33 »
Ano, jen 3. Projekt se navrhne, napise, odladi, spusti a udrzuje. Klicove slovicko, ktere jste zjevne zamerne ignoroval je "netrivialni". Napiste mi prosim, na kolika netrivialnich projektech (rekneme nad 50 000 radek), v C (ne C++) jste se podilel Vy.

Nevím, nepočítal jsem to, budou to desítky. Když vezmu jen rok 1996-2000, tak ty tři hravě překonám (těch 50tis řádek beru jako rozhodující míru)

Re:C++ a výjimka
« Odpověď #177 kdy: 12. 02. 2014, 17:28:05 »
Ano, jen 3. Projekt se navrhne, napise, odladi, spusti a udrzuje. Klicove slovicko, ktere jste zjevne zamerne ignoroval je "netrivialni". Napiste mi prosim, na kolika netrivialnich projektech (rekneme nad 50 000 radek), v C (ne C++) jste se podilel Vy.

Proč jenom v C? V C jsem napsal asi dva až tři velké projekty, když jsem zjistil, že takhle to dál nejde, a komplet jsem přesedlal na C++, kde mám spoustu projektů. Prostě nebudu se vracet ke starým technologiím, dokud vyloženě nemusím (naposledy při portování Skeldalu na iPhone, naštěstí jsem jen vypomáhal)

Sten

Re:C++ a výjimka
« Odpověď #178 kdy: 12. 02. 2014, 18:33:30 »
Ano, firefox Vam napovi, ale pouze z VELMI OMEZENEHO mnozstvi chybovych stavu - coz je presne to o cem mluvim - firefox Vam nenahlasi KAZDOU MOZNOU CHYBU - pouze nekolik, ktere si podle vyvojaru zaslouzi vlastni "kategorii". Pro vsechno ostatni bude "selhalo spojeni". Coz, jak rikate "napovi", nicmene se jedna o to, o cem mluvim ja - "zabaleni" vyjimky - firefox Vam nepovi o tom, jaky errorcode vratil "socket", nerekne vam na jake pozici doslo ke korupci paketu. Napise "selhalo spojeni", protoze to je ta "zabalena" chyba/vyjimka. Natoz aby Vam rekl ze jste blbec a ze jste si vykopnul kabel.
Coz souvisi s tim cemu se obcas rika "leaky abstraction" - proste kazda vyssi vrstva je ve vetsine pripadu nucena provest nejake "zobecneni" urcitych chybovych stavu pod jednu "strechu". Pak NENI mozne bez dalsich nastroju zjistit, kde k chybe doslo. To je ale normalni, a je to v poradku. Firefox nema slouzit jako diagnostika site. Na to jsou jine nastroje.

Firefox samozřejmě není diagnostika sítě, ale měl by říct co nejdetailněji, co ví, že se stalo, aby bylo možné to snadno opravit. V tom mají výjimky oproti chybovým kódům velkou výhodu, mohou mít leaky abstraction a zároveň v sobě nést detailní informace (např. reason a backtrace), které jsou pro snadnou a rychlou opravu problémů poměrně zásadní. Nedovedu si moc představit, jak bych u uživatele ladil problémy s Bluetooth, kdybych dostal akorát Could not connect a nevěděl ani, ze které funkce to vypadlo. A ne, uživatel opravdu nedokáže spustit debugger.

belzebub

Re:C++ a výjimka
« Odpověď #179 kdy: 12. 02. 2014, 20:27:54 »
Ano, jen 3. Projekt se navrhne, napise, odladi, spusti a udrzuje. Klicove slovicko, ktere jste zjevne zamerne ignoroval je "netrivialni". Napiste mi prosim, na kolika netrivialnich projektech (rekneme nad 50 000 radek), v C (ne C++) jste se podilel Vy.

Proč jenom v C? V C jsem napsal asi dva až tři velké projekty, když jsem zjistil, že takhle to dál nejde, a komplet jsem přesedlal na C++, kde mám spoustu projektů. Prostě nebudu se vracet ke starým technologiím, dokud vyloženě nemusím (naposledy při portování Skeldalu na iPhone, naštěstí jsem jen vypomáhal)

Protoze ja mluvim celou dobu o osetrovani chyb pomoci errorkodu v C. VC. Chapu ze ve Vasi snaze me argumety ignorovat jste to pochopil tak, ze za cely zivot jsem se ucastnil 3 projektu vseho vsudy. PROTO jsem psal "v C".
Cela pointa toho odstavce byla ukazat Vam, ze nevite jak delat spolehlive a velke projekty v C.
Jinak pokud Vim, iPhone pouziva ObjC, ne C.