Archief - [C++]Exceptions

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

Fristii

Legacy Member
Hallowa

Overtlaatst hadden een paar mensen een nogal verhitte discussie over het gebruik van exceptions.

Het punt was wanneer ze net te gebruiken. Telkens komt men weer op "in uitzonderlijke gevallen", maar wat moet men net verstaan onder uitzonderlijke gevallen?

Als ik een library schrijf met methodes met precondities en dergelijken, vanaf wanneer moet ik een exception voorzien? Tot op welk punt mag ik het overlaten aan de gebruiker om er zijn plan mee te trekken?

Ik bedoel, als ik duidelijk gedefinieerde precondities heb (en methodes voorzie ter controle) dan is het de verantwoordelijkheid van de gebruiker om er rekening mee te houden.

Voor bijv. user input gebruiken we geen exceptions.

Het punt is dat deze lijn nogal vaag is, iemand tips/richtlijnen hierover?

Greets
Fristii

Cycloon

Legacy Member
Het zal wel beter zijn om met een exceptie te werken. Wanneer de gebruiker dan toch foute zaken ingeeft (met opzet of per ongeluk) dan kan je de exceptie opvangen en om nieuwe input vragen.

Ook al zeg je wat de gebruiker mag ingeven en wat niet, het is altijd handig voor als de gebruiker zou missen of er een nieuwe gebruiker je systeem gaat gebruiken.

Obliv`

Legacy Member
Als je method niet kan doen wat er van verwacht wordt, moet je een exeption geven. Bijvoorbeeld: een parameter is null, terwijl dat niet zou mogen => ArgumentNullException in C#.

In jouw geval vind ik het helemaal correct dat je een exception geeft wanneer er niet aan de precondities voldaan is.

Voor user input zou ik ook geen exceptions gebruiken. Je valideert gewoon het object waarin de gegevens terecht komen. Als de gegevens niet goed zijn, geef je een error op de save. Ik zou wel er zo goed mogelijk voor proberen te zorgen dat de gebruiker gewoon geen foutieve gegevens kan ingeven. Bijvoorbeeld dingen als comboboxes waar mogelijk.

forloRn_

Legacy Member
Obliv` zei:
Als je method niet kan doen wat er van verwacht wordt, moet je een exeption geven. Bijvoorbeeld: een parameter is null, terwijl dat niet zou mogen => ArgumentNullException in C#.

Dat vind ik goed verwoord. Exceptions dwingen je gebruiker om fouten af te handelen, en bieden de mogelijkheid om die afhandeling in een centrale plaats te doen: het catch-block. In tegenstelling tot bijvoorbeeld return values kunnen exception in principe niet genegeerd worden, tenzij je een leeg catch-block schrijft, maar dan ben je gewoon slecht aan het programmeren.

Obliv` zei:
Voor user input zou ik ook geen exceptions gebruiken. Je valideert gewoon het object waarin de gegevens terecht komen. Als de gegevens niet goed zijn, geef je een error op de save. Ik zou wel er zo goed mogelijk voor proberen te zorgen dat de gebruiker gewoon geen foutieve gegevens kan ingeven. Bijvoorbeeld dingen als comboboxes waar mogelijk.

En dat vind ik hier een bijzonder slecht idee. MVC zegt dat model en view in principe onafhankelijk van elkaar moeten kunnen bestaan. Validatie van input moet er zijn, bijvoorbeeld in het geval van webapplicaties zodat je geen onnodige trips naar de server maakt, maar je business logic moet ook nog werken wanneer je geen impliciete checks doet op de invoer (comboboxes). Dus: preconditions checken aan het begin van de method. De method zal immers toch falen; dan kan je er maar beter zo snel mogelijk komaf mee maken (en 't is nog handiger bij het debuggen ook).

Moto

Legacy Member
Als je method niet kan doen wat er van verwacht wordt, moet je een exeption geven. Bijvoorbeeld: een parameter is null, terwijl dat niet zou mogen => ArgumentNullException in C#.

Weet niet hoe het in C++ is maar in C# kost het trouwen van exceptions + catchen een hele hoop aan performance
In zo'n geval test ik bij het begin van de function op null anders return
Enige exceptions die ik in mijn huidig project catch zijn oracle exceptions, voor de rest throw ik zelf zo goed als niks

Het is natuurlijk een ander verhaal als ge een library maakt voor 3rd parties

Cycloon

Legacy Member
Als performantie je probleem is moet je ook alle object geörienteerde zaken zoals klassen overboord gooien en proceduraal gaan programmeren. Excepties niet gebruiken met als argument slechte performantie dan ben je echt wel fout bezig (tenzij je in een omgeving zit waar je erg grote hardware beperkingen hebt).

forloRn_

Legacy Member
Moto zei:
Weet niet hoe het in C++ is maar in C# kost het trouwen van exceptions + catchen een hele hoop aan performance
In zo'n geval test ik bij het begin van de function op null anders return
Enige exceptions die ik in mijn huidig project catch zijn oracle exceptions, voor de rest throw ik zelf zo goed als niks

Het is natuurlijk een ander verhaal als ge een library maakt voor 3rd parties

Wat Cycloon al zei: performance mag geen reden zijn voor een slecht design. Exceptions throw je enkel in uitzonderlijke omstandigheden, vandaar de naam; ze spelen bijgevolg normaal gezien geen rol bij performance.

Moto

Legacy Member
Als performantie je probleem is moet je ook alle object geörienteerde zaken zoals klassen overboord gooien en proceduraal gaan programmeren. Excepties niet gebruiken met als argument slechte performantie dan ben je echt wel fout bezig
"zo goed als niks" != "niet gebruiken"
Het voordeel van klassen tov performance is VEEL groter dan exceptions hier en daar derinsteken waar niet nodig
Als ge in elke functie in C# eerst uw params gaat checken en excepties gaat throwen als er iets fout is zijt ge gewoon slecht bezig
performance mag geen reden zijn voor een slecht design
Enkel exceptions gebruiken zoals ge zelf zegt in uitzonderlijke omstandigheden is GEEN slecht design, return van booleans ed is veel sneller/properder/beter.
Voor de dingen die ik maak dek ik alles zo goed af dat er praktisch geen uitzonderlijke omstandigheden zich kunnen voordoen. vandaar ook praktisch geen eigen exceptions + exceptions die ik opvang bv van oracle worden niet gerethrowd naar de client maar worden ook afgehandeld met return values

performance btw IS belangrijk, heb al in mijn loopbaan al genoeg trage rommel van anderen mogen herschschrijven, beter "Goed design mag geen reden zijn voor slechte performance" als motto nemen.

forloRn_

Legacy Member
Moto zei:
Enkel exceptions gebruiken zoals ge zelf zegt in uitzonderlijke omstandigheden is GEEN slecht design, return van booleans ed is veel sneller/properder/beter.
Voor de dingen die ik maak dek ik alles zo goed af dat er praktisch geen uitzonderlijke omstandigheden zich kunnen voordoen. vandaar ook praktisch geen eigen exceptions + exceptions die ik opvang bv van oracle worden niet gerethrowd naar de client maar worden ook afgehandeld met return values

performance btw IS belangrijk, heb al in mijn loopbaan al genoeg trage rommel van anderen mogen herschschrijven, beter "Goed design mag geen reden zijn voor slechte performance" als motto nemen.

Je verdraait mijn woorden gewoon. Ik zeg dat exceptions (fouten) op zich eerder uitzondering dan regel moeten zijn, niet dat je maar zelden exceptions moet gebruiken om fouten op te vangen; integendeel: ik zeg dat je overal exceptions moet gebruiken.

Er zijn redenen waarom ze die dingen in de eerste plaats uitgevonden hebben; enkele daarvan heb ik hierboven al aangehaald. Andere reden zijn dat je in een exception een volwaardige klasse is waarin je veel meer informatie kan stoppen dan in een boolean of een int als return value, en dat je nog eens op de compiler kan rekenen om alles type-safe te laten verlopen.

Je gaat me echt niet wijsmaken dat je ooit "trage rommel van anderen" sneller hebt doen runnen door louter exceptions te vervangen door return values. Spendeer je tijd nuttig, haal een profiler boven en herschrijf de trage gedeelten van je programma; stap in extremis over op een taal die omgezet wordt in native instructies of upgrade gewoon je hardware want deze is duidelijk niet gemaakt voor de dingen die je ermee wilt doen.

Exceptions omzetten in return values! Proficiat, je hebt de voordelen van exceptions mooi tenietgedaan. Ik zou niet graag de persoon willen zijn die na jou de code moet onderhouden.

Cycloon

Legacy Member
forloRn_ zei:
Exceptions omzetten in return values! Proficiat, je hebt de voordelen van exceptions mooi tenietgedaan. Ik zou niet graag de persoon willen zijn die na jou de code moet onderhouden.

Of de persoon die achter hem een stuk van zijn code wil gaan hergebruiken. Die mag dan gaan uitzoeken wat alle mogelijke speciale return values zijn en hoe hij ze moet interpreteren. Ook maakt het de code die met zijn code moet werken een heel pak complexer (in de zin van: veel extra if constructies om te kijken of er geen speciale return values zijn).

Anyway, hij leek al overtuigd te zijn van zijn methode nog voor hij het hier kwam vragen, het lijkt mij dan ook nutteloos om hem te proberen overtuigen.

Obliv`

Legacy Member
forloRn_ zei:
Dat vind ik goed verwoord. Exceptions dwingen je gebruiker om fouten af te handelen, en bieden de mogelijkheid om die afhandeling in een centrale plaats te doen: het catch-block. In tegenstelling tot bijvoorbeeld return values kunnen exception in principe niet genegeerd worden, tenzij je een leeg catch-block schrijft, maar dan ben je gewoon slecht aan het programmeren.



En dat vind ik hier een bijzonder slecht idee. MVC zegt dat model en view in principe onafhankelijk van elkaar moeten kunnen bestaan. Validatie van input moet er zijn, bijvoorbeeld in het geval van webapplicaties zodat je geen onnodige trips naar de server maakt, maar je business logic moet ook nog werken wanneer je geen impliciete checks doet op de invoer (comboboxes). Dus: preconditions checken aan het begin van de method. De method zal immers toch falen; dan kan je er maar beter zo snel mogelijk komaf mee maken (en 't is nog handiger bij het debuggen ook).

Inderdaad, dat tweede stuk heb ik niet goed verwoord. Ik volg dus ook jouw mening. Ik bedoelde met input constrainen dus ook het gebruik van validators en dergelijke.

Obliv`

Legacy Member
Moto zei:
Enkel exceptions gebruiken zoals ge zelf zegt in uitzonderlijke omstandigheden is GEEN slecht design, return van booleans ed is veel sneller/properder/beter.

Voor de dingen die ik maak dek ik alles zo goed af dat er praktisch geen uitzonderlijke omstandigheden zich kunnen voordoen. vandaar ook praktisch geen eigen exceptions + exceptions die ik opvang bv van oracle worden niet gerethrowd naar de client maar worden ook afgehandeld met return values

Zeer fout bezig in mijn ogen dan. Je ziet dit soort zaken dikwijls terugkomen bij juniors. Wanneer ze dan een code review krijgen van een meer ervaren persoon, is het gebruik van return values ipv exceptions dikwijls het eerste waarvoor ze tegen hun kloten krijgen.

Je kan het gebruik van return values misschien handig vinden, maar als je op een project zit waar je met pakweg tien mensen aan werkt, zal er altijd wel iemand zijn die de return value vergeet te checken. Terwijl de fout bij deftige exception handling altijd wordt opgevangen.

En dan nog met die performance? Is er een performance penalty bij het gebruik van exceptions? Zeker en vast! Maar is die penalty in de meeste gevallen zo kritisch? In 99% niet denk ik.

Ik zeg nu ook niet dat je voor alles een exception moet gaan opwerpen hé. Als je ze kan vermijden moet je dat ook doen. Bijv File.Exists check voordat je een bestand opent. Zo kan je in ieder geval al geen FileNotFoundException krijgen.

Moto

Legacy Member
Zeer fout bezig in mijn ogen dan. Je ziet dit soort zaken dikwijls terugkomen bij juniors.
lol, juniors, zie eerder andere fouten bij juniors als ik ze review namelijk zaken gebruiken zoals exceptions en design patterns en frameworks waar totaal niet nodig, waardoor hun code bloated en traag wordt

Misschiens nog eens de OP lezen
Ik bedoel, als ik duidelijk gedefinieerde precondities heb (en methodes voorzie ter controle) dan is het de verantwoordelijkheid van de gebruiker om er rekening mee te houden
In mijn ogen wel, behalve dus als ge uw library op zich verkoopt aan 3rd parties

Stel nu een library met functies die een object accepteren, ik throw geen exception als het object null is, stel nu dat er dan een ander component wordt aangesproken stuk hardware dat normaal available moet zijn, dan wordt er pas een excpetion gethrowd, als er echt niet anders opzit, maar dan hangt het nog van de situatie af voor misschien een return value te gebruiken, en als er dan een exception gethrowed moet worden, dan komt die call-stack in de log-file, en ga ik niet volledige exceptions met callstacks en alles over de lagen heen en weer gooien.

Ik zou niet graag de persoon willen zijn die na jou de code moet onderhouden.
lol, omdat ik zo weinig mogelijk exceptions gebruik heb ik slecht design, komt eens over een paar jaar terug zou ik zeggen, als ge wat ervaring hebt :p

Krueger

Legacy Member
Moto zei:
Stel nu een library met functies die een object accepteren, ik throw geen exception als het object null is, stel nu dat er dan een ander component wordt aangesproken stuk hardware dat normaal available moet zijn, dan wordt er pas een excpetion gethrowd, als er echt niet anders opzit, maar dan hangt het nog van de situatie af voor misschien een return value te gebruiken, en als er dan een exception gethrowed moet worden, dan komt die call-stack in de log-file, en ga ik niet volledige exceptions met callstacks en alles over de lagen heen en weer gooien.
:p

Hoe ga je dan te werk? Stel dat je normaal een object van een klasse returned als functie foo wordt aangeroepen.

De user geeft een null-klasse mee, return je dan null ?
En als er bepaalde waarden niet zijn ingevuld, wat return je dan?
En als alles is ingevuld, maar je berekening toch faalt, omdat het om een of andere reden niet uitrekenbaar is.
of ...


Dan zit je toch beperkt met je returnvalues? Je kan zeer moeilijk een onderscheid maken in al die situaties. Maar met excepties kan je veel meer informatie meegeven.

Als je een 3th part lib schrijft, schrijf je dan documentatie in de zin van als returnwaarde 5041 is: volgende fout, returnwaarde 15645: fout zoveel. Merk op dat je dan wel beperkt bent tot return values met ints, en niet met klasses.

killgore

Legacy Member
Mijn mening (ik heb heus niet alles gelezen):
-Is uw code tijd-kritisch : gebruik sowieso geen exceptions en val terug op goede oude methoden. (excepties zijn doorgaans vrij traag).
-Is dit niet het geval: elke fout waar gij niets aan kunt doen om ze te verhelpen (en dat is in 99.99% van de gevallen door foute input) moet een exceptie genereren. Bv:
Code:
int myDiv(int a, int b)
{
    if(!b) //GOOI EXCEPTIE
    return a/b;
}

Het is heel duidelijk dat uw normale algoritme alle input aanvaard behalve b=0, daar kan je geen wiskundig geldige return value voor leveren en is dus een fout waar jij niets aan kan doen. Dan gooi je een exceptie.

Een vb. waar je het wel kan opvangen als je wilt (ik zou een exceptie aanraden :p):
Code:
int myDiv(int a, int b)
{
    if(!b) return numeric_limits<float>::quiet_NaN();
    return a/b;
}

excepties zijn er juist gekomen zodat je niet moet beginnen prutsen met 'out' parameters voor echte return en gewone return voor status (err msgs ...).

Fristii

Legacy Member
Bedankt voor alle antwoorden al.
Twas gewoon verwarrend aangezien prof en assistent elkaar tegenspraken -.-"..

Maar ben der wel uit nu denk ik :)

Thanks a lot!

Moto

Legacy Member
Hoe ga je dan te werk?
De user geeft een null-klasse mee, return je dan null ?
Library voor intern gebruik, ja, verantwoordelijkheid wordt voor een deel ook geplaatst bij collega's die het gebruiken, trouwens soms is het returnen van null dan ook gewenst
En als er bepaalde waarden niet zijn ingevuld, wat return je dan?
bv bepaalde waarden van het object dat ge meegeeft?, als waarden zowiezo nodig zijn, dan staan die ook in de constructor
En als alles is ingevuld, maar je berekening toch faalt, omdat het om een of andere reden niet uitrekenbaar is.
Dan zit je toch beperkt met je returnvalues? Je kan zeer moeilijk een onderscheid maken in al die situaties. Maar met excepties kan je veel meer informatie meegeven.
Welke info? call-stack info? :p
Soms volstaat een simpele return uit een functie
Soms volstaat een boolean
Soms wil je alle zaken weten die niet kloppen en dan loopt ge de functie af en returned ge op een deftige manier alle fouten die der instaan (geen cryptische nummerkes!)
en heel soms is een exception het beste

Je kan natuurlijk ook in elke functie een aantal exceptions voorzien en in elke call try catch blokken steken (dit was dus de vraag van de op), maar waar zijn we dan mee bezig, het beste is dat gewoon proberen te vermijden (dus ik praat hier nog altijd over internal libs)

Als je een 3th part lib schrijft, ...
Zoals ik al eerder vermelde, deftige exceptions gebruiken.
Dus 3rd party bedoel ik stuff die ge effectief aan andere bedrijven verkoopt

Obliv`

Legacy Member
Moto zei:
bv bepaalde waarden van het object dat ge meegeeft?, als waarden zowiezo nodig zijn, dan staan die ook in de constructor

En als je null meegeeft als parameter aan de constructor? Of als het een static function moet zijn?

Moto zei:
Je kan natuurlijk ook in elke functie een aantal exceptions voorzien en in elke call try catch blokken steken (dit was dus de vraag van de op), maar waar zijn we dan mee bezig, het beste is dat gewoon proberen te vermijden (dus ik praat hier nog altijd over internal libs)

OK, ik ga ermee akkoord dat je ze moet vermijden als het mogelijk is. Maar als het niet mogelijk is, ga dan toch niet grijpen naar specifieke return values en neem een propere exception ;). (zie killgore)
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan