Zalezi na tom, co z C++ chteji vyuzivat. Pokud by zustali vicemene u programu v C a za C++ vyuzili pouze nektere konstrukce, ktere by zjednodusily zapis struktur, nic bych proti tomu nemel.
Ovsem pokud by se pak kernel dostal do stavu, kdy by se vyzivaly classe s konstruktorama a destruktorama a co hur, funkce, co maji stale stejne jmeno, ale lisi se podle toho, jake jim predas parametry, to by vedlo k silenym zmatkum. Nevim jak vy, ale s C++ mamnekdy potize s tim, ze neni vubec jasne ktera verze funkce se zavola, protoze nekdy neni jasne jak se nektere parametry samy zkonvertuji treba z char na int a podobne. Nebo co hur, pridas dalsi verzi funkce s jinou kombinaci parametru a cast programu, na kterou jsi nesahnul, prestane fungovat, protoze se z nej zacne volat jina verze funkce, protoze parametry se zkonvertuji jinak. Stejne tak byva zmatek s destruktorama - nikdy nevis, v jakem poradi se zavolaji.
Proste podle me je C++ krasne, pise se v nem dobre, ale je znacne nedeterministicke.
Přesně.
Toto je jedna z věcí, kterou Rust udělal fakt dobře - žádné exceptions, žádný problém. Exceptions jsou feature, která přináší víc škody než užitku a dodnes je celá C++ komunita rozdělená na 2 tábory... C++ bez exceptions a s exceptions to jsou v podstatě 2 světy, které nejdou k sobě a dnes už se s tím nedá nic dělat.
Vyjimky se mi celkem libi. Silne to zjednodusuje program. Ale je pravda, ze pak staci neosetrit jednu vyjimku a jsou z toho problemy. Ja pisu spis drivery, web services a podobne, takze tam se to pouziva celkem dobre. Proste vznikne vyjimka, na nejvyssi urovni se odchytne a vrati se packet s errorem. Pak nemusi byt program prospikovany testem za kazdou funkci, aby clovek zjistil, ze nekde nastala chyba. Predtim jsem psal programy stylem, ze kazdy radek vypadal plus minus takhle:
if (!e) e=operace(parametry);
Pripadne
e=e||operace(parametry);
Ale takhle se neda psat program.
Podívej se na Rust, jak se dá psát program - tam ten error handling je celkem dobře udělaný i bez exceptions a něco takového kdyby bylo v C++, tak bych neměl moc důvod dívat se jinam.
Problém exceptions ale není jen toto - udělat review kódu, kde se používají exceptions prostě není možné, a proto se někde vůbec nesmí používat. Jenže když se nepoužívají, tak pak celé C++ se používá dost špatně, protože si člověk musí implementovat všechno sám bez exceptions a na propagaci chyb se pak nejlíp používají různé makra. A právě toto má Rust udělané mnohem líp.
Tak já třeba Rust používám jako jeden z mých hlavních jazyků, a absence výjimek mě tam spíše mrzí. Ano, dá se to používat, neříkám nic. Ale nejsem přesvědčen, že by to bylo čitelnější.
Abych doplnil důležitý bod: obhajuji kontrolované výjimky - tedy, když vytvořím funkci, která volá funkci, která může vyhodit výjimku, a já ji nekontroluji, tak to musím v signatuře dát vědět. Jinak to přehledné být přestane.
Nutnost řešit, že funkce může vracet chybu při volání té funkce, mi přijde z architektonického hlediska zbytečně zbabělé.
A právě toto má Rust udělané mnohem líp.
Ok, filozoficky: jak se liší Exception od std::panic::catch_unwind a panic!? Pokud je někdo pr*se a řídí pomocí Exception flow programu, může to teoreticky řídit i catch_unwind. Podle mě zásadní neopochopení Exceptions (ačkoli se to píše snad všude) je že lidé toho zneužívají k řízení programu a ne k signalizaci "výjmečného" stavu
15. 1. 2024, 16:48 editováno autorem komentáře
Výjimečný stav v C++ definuje 10 z 10 C++ programátorů jinak, dokonce se v mnoha případech neshodnou ani lidi ve stejném teamu. Toto je moje zkušenost.
- https://doc.rust-lang.org/std/panic/fn.catch_unwind.html
Zrovna v Rustu má podle mě panic jasný význam: Neopravitelná chyba. Což je trochu něco jiného než jak s výjimkama pracuje C++.
Neočekávaný stav není ve všech situacích stejně neočekávaný a také k němu nebudete vždy přistupovat stejně. Někdy chcete aplikaci ukončit, ale někdy chcete, aby se zotavila, pokračovala dál, nebo zopakovala volání (časté u síťových operací). Těch příkladů lze najít celou řadu. Je naprosto legitimní použít exceptions pro řízení flow programu nebo jeho části, pokud to dává smysl.
Bohužel není vždy jednoduché se správně rozhodnout a také ta výchozí situace se může v průběhu času změnit.
A proto se mi líbí přístup Rustu, kde vlastně není chyba nijak výjimečná, jen je reprezentována typem Result a který lze jednoduše převést na Option když je potřeba.
Navíc se dá snadno zakázat neošetření výjimky lintem. Občas se sice hodí povolit expect v případě kdy chyba reálně nemůže nastat, ale i pak je fajn mít to zakázané, snáz to donutí vývojáře explicitně povolit výjimku a dokumentovat proč.
Tohle mě na Rustu opravdu baví. Oproti C/C++ nacházím v existujícím kódu mnohem míň pastí.