( TCH | 2021. 03. 23., k – 12:09 )

A C++-os try/catch sokkal több, mint az if, belül egyáltalán nem az van, amit ezekszerint gondolsz. Hiszen ahol elkapod az exceptiont, az sokkal feljebb is lehet a call stacken, mint ahol dobtad. És közben szépen minden köztes fv-ben lerakott objectnek is meghívódik a destruktora. Manapság az exception nem úgy működik, hogy lesz a fv-ednek valami rejtett visszatérési értéke, amit a hívott oldal rejtve csekkolgat. Ha nem dobsz exceptiont, akkor nem is kell csekkolni semmit. Emiatt akár gyorsabb is lehet a kód, ha exceptionnal jelzed a hibát.

Nem erre gondoltam, hanem arra, hogy a kivételkezelés belül egy halom if-re és elseif-re fog fordulni, ami a keletkezett exception értékekkel dolgozik, vagy ez már nem így van? Hogy néz ki a végeredmény belül?

A mostani C++ fordítók zero cost exceptiont használnak. Ami egy kicsit félrevezető név, mert csak akkor zero cost, ha nem dobsz exceptiont. Ha dobsz, akkor viszont az lassú. Viszont, erre a memóriaelfogyásos dologra tökéletes megoldás. Sehol se kell bajlódnod azzal, hogy csekkold a malloc() visszatérési értékét, hanem valahol magasabb szinten elkapod az out_of_memory exceptiont, és kész. Ha a resource-okat RAII-val allokálod (ez manapság teljesen alap), akkor minden automatán menni fog, minden resource amit a köztes fv-ek allokáltak felszabadul szépen mindenféle külön kezelés nélkül.

Ez a zero cost amúgy sem túl tiszta, mert három C++ fejlesztő négyféleképpen magyarázza, Bjarne meg évszámtól függően.

Ugyanezt a logikát C-ben végigprogramozni kézzel... Hát, ha ilyen kódot kellene írnom C-ben, szerintem felmondanék.

C-ben erre nincs is szükség, hiszen a mechanizmusok sem ennyire bonyolultak.

Inkább azt mondanám, hogy már van helyette jobb.

Mire jobb és miben jobb? :) Hordozhatóságban alig hinném, hogy bármi übereli. Teljesítményben is kb. csak az assembly, de az is csak akkor, ha vagy nem "bonyolult" a CPU (spekulatív végrehajtás, OOO végrehajtás, stb.), vagy az assembly-ző kóder nagyon penge; egyéb esetben a C kb. jobb assembly kódot fog generálni, mint amit a kóder írna. (Ezt egyszer kiveséztük.)

De tudok mondani rendes példát is. C-ben írt kernelmodul, ahol a device drivernek a mindenféle paramétereit egy structban tárolják, és a modul betöltésekor szépen lépésről lépésre kitölti minden memberjét egy-egy fv. Nos, ezt C-ben úgy oldották meg, hogy a kitöltő fv-t kiemelték egy 20 soros macro-ba, majd kb. 10x meghívták különböző paraméterekkel, hogy a ~10 member értéke beállítódjon (mivel a fv-ek amik kitöltik a membereket, nagyon hasonlóak egymáshoz). Ha ezt C++-ban csinálom, megírom szépen template fv-ben, és kapok egy normálisabb megoldást. Lefordított kódméret ugyanakkora, nincs semmi hátránya a C-s megoldáshoz képest. De tudnék még ilyen példákat hozni.

Ezt C-ben is lehet, hogy ki lehetne egyszerűsíteni; ezt a Linux kernelben láttad, vagy nem publikus céges cucc?