( geza42 | 2020. 09. 26., szo – 23:12 )

 Egy ciklus belsejében nyilván nincs értelme újraellenőrizgetni a dolgot

Jó, de érted, ha egy részről azt mondod, hogy egy fv ellenőrizze le a paramétereit, és az operator[] az egy fv, és használnánk egy matrix szorzó rutinban, akkor ott lesz a felesleges ellenőrzés. Ez abból a szempontból speciális eset, hogy tök egyszerűen látható, hogy jelentős performance veszteség a vége. De egyébként meg kb. az összes helyen, ahol operator[]-t hívunk, felesleges az ellenőrzés, hiszen szinte soha se megy rá a vezérlés. Ergo mindenhol performance csökkenést okoz. És nagyobb kódot. Nem pár KB-t. Hányszor van leírva egy kódban az indexelés? Rengetegszer. Mivel inline-oljuk, ezért meg fog nőni a kód mérete. Jó, mind1, nem akarok ezen tovább rugózni amúgy, kb. megbeszéltük.

 

ez ilyen ökölszabály, hogy a bemenetet illik leellenőrizni.

Sokaknál ez az ökölszabály, sokaknál meg nem. Nálam pl. tutira nem. Assert-et nagyon sokat használok, de azt szeretem, hogy release-ben gyorsan menjen a kód (azaz release-ben egy csomó fv paraméterei nincsenek ellenőrizve).

 

plusz egy nested-függvényhívás, ez sokkal súlyosabb overhead lesz, mint az egy darab elágazás a függvényen belül.

Ha csak egy plusz elágazásról beszélünk, akkor az be tud inline-olódni (annak minden hátrányával együtt), szóval súlyos overheadnek azért nem mondanám. Ill., nyilván csak akkor van értelme azt a verziót meghívni, ha nem tudjuk kizárni, hogy fennállhat a hiba lehetősége. Persze ezzel visszajuthatunk az elejére, hogy mikor melyik verziót kell használni, és ha a hibakezelés nélküli verziót használjuk, akkor ott a baj.

 

Ennyi erővel azt is csinálhatná a fordító, amit fentebb asch javasolt, hogy ha látja, hogy "kint" leellenőrizték a hívás előtt, akkor belülről kidobja az ellenőrzést. Mert mi van, ha nem ellenőrizték le? Akkor jönnek a crash-ek, meg a sechole-ok.

Igen, csinálják is a fordítók szerencsére ezt, ha inline az ellenőrzés kódja, vagy link time optimizationnal van fordítva. Persze ez még messze nem tökéletes, mert sokszor nem tudnak rájönni a felesleges ellenőrzésekre.

 

Most komolyan pár if, meg return miatti plusz kB-okon akadunk fent, miközben több GB-os "framework"-ökre épül szinte az egész szoftvervilág? :(

Nem feltétlenül a lefordított kód méretére gondoltam, hanem a forráskódéra. Hogy minden libc hivás után ott lesz a hibakezelés. Egyébként tutira nem pár KB-ról beszélünk, ha minden fv-ben ott a hibakezelés (és az azt meghívó kódban is). Szerintem simán százalékot lehetne mondani, hogy mennyivel lesz nagyobb a kód egy ilyentől. De csak hogy ne a levegőbe beszéljek: azon a kódon, amin dolgoztam az előző munkahelyemen, az assertes és nem assertes build között majdnem 2x méretkülönbség, és hasonló sebességkülönbség van (úgy értve a buildeket, hogy mind2 optimalizált; az egyikben ott vannak az assertek, a másikban pedig nincsenek). Nyilván ez csak egy project, máshol más számok lehetnek, de azért beszédes szerintem.

 

Én. Nekem valami defektus miatt a mániám, hogy ha egy függvény visszaadhat valamilyen hibakódot, akkor azt lekezelem.

Itt most arról az esetről beszélünk, hogy a hiba "elviekben" nem történhet meg, mert az programozó hibát jelent. Tehát, ha egy memcpy-t tutira nem NULL paraméterekkel hívom meg, akkor nem akarok hibakezelést se tenni a hívás után, mivel tudom, hogy soha nem fog rámenni a futás. Ergo nem is akarok lekezelni egy ilyen hibát.

 

Most akkor miről vitatkozunk?

Szerintem azt a vitát ne hozzuk be ide, mert teljesen másról szólt. Ott nem arról volt szó, hogy hogyan kezeljük le a programozók által elkövetett hibákat. Ott az exception kezelésről beszéltem, és arról, hogy szerintem az exc. kezelésnek az a feature-e, hogy eldobod, aztán valaki sokkal feljebb kapja el, nem sok értelme van. Hasznos tud lenni néha, de ha jó hibakezelést akarunk, akkor ez ritkán használt feature, és inkább az lesz belőle, hogy az emberek lusták lesznek hibát kezelni.

 

Azt viszont valahogy nem nagyon tudom értelmezni, hogy össznépileg megszavazzuk, hogy validálni nem kell, aztán meg a C rossz, mert segfault és buffer overflow...

Nem arról van szó, hogy összességében sehol se kell validálni, hanem arról, hogy az a szabály, hogy "a fv elején mindig validáljuk a paramétereket" nem feltétlenül állja meg a helyét. A C pedig igenis egy rossz programozási nyelv így 2020-ban. Valamikor jó nyelv volt, de azóta már vannak jobb programozási nyelvek. Vitázni én se akarok erről különösebben, csak azért lássuk be, hogy a világ elment a C mellett. Konkrétan szinte nincs olyan feladat, amit C-ben állnék neki megcsinálni, ha from-scratch kell valamit alkotni. Egy előnye van C++-szal szemben, hogy az ABI az nagyon kőbevésett, nincs vele problméma (persze C++-s kódhoz is lehet C-s API-t csinálni, sokan csinálják is). Ha ez nem számít, akkor el nem bírom képzelni, miért használna bárki C-t (mivel hogy C++-ban is kb. lehet C-ben programozni, és ha kell, akkor ott van a C++ összes jó feature-e).