Safe & secure programming

Pagina: 1 2 Laatste
Acties:
  • 694 views sinds 30-01-2008
  • Reageer

  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
Regelmatig zie ik stukje code voorbij flitsen die mijn tenen doen krommen. Sommigen zijn nodig voor eenvoudige uitleg zonder smuk maar anderen zijn zo uit code ge-cut en paste. Soms kan ik mij niet inhouden en moet ik daar wat van zeggen. Vandaag was het weer zover ... single point of exit :) http://gathering.tweakers.net/forum/list_messages/1136605 .

Voor mijn werk moet ik enorm failure safe schrijven, voor de hobby en simpele applicaties hoeft dat natuurlijk niet allemaal ... maar allemaal niet is ook niet goed, waar ligt de grens.

Wat is in jullie ogen een goede balans tussen goede code schrijven en het voor de hobby ook nog een beetje snel afhebben? Belangrijke beperking in deze discussie is wel dat het een consequente keuze moet zijn, dus bijv. na een if altijd {} ook als er maar 1 statement is. Geen taal specifiieke keuzes al denk ik dat de overgrote kudde goed overweg kan met C, PHP en Java. Dus bij voorkeur deze gebruiken in code snippets.

Wat vuurwerk om mee te beginnen:
  • Single point of exit (dus maar 1 return statement)
  • Altijd booleans checken tegen hun waarde (a==true)
  • Altijd nieuwe context in {} zetten, ook bij 1 statement
  • Nooit meerder statements op 1 regel (for loop is uitzondering, ++=1 statement)
  • Functies nooit aanroepen met berekeningen in de parameter list (drukaf(2*b+1);)
  • else...if constructies die meer als twee keer genest zijn, verbieden.
  • (enterance/exit tracing van een functie)

[ Voor 85% gewijzigd door .oisyn op 29-05-2006 21:41 ]

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 00:09

Janoz

Moderator Devschuur®

!litemod

Dat er maar 1 return voor mag komen is natuurlijk onzin. Er moet minimaal 1 return in elk mogelijk executiepad binnen een functie voorkomen die iets zou moeten returnen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
Ik weet dat je moderator bent, ga er vanuit dat je veel gezien hebt, maar hier moet ik toch zeggen dat ik het heel sterk met je oneens ben. Nette functies kennen maar 1 return (single exit point). Heb al vele stukken code gereviewed in de afgelopen 10-15 jaar die door pragmatisch programmeren fouten opleveren (en ikzelf maak me daar ook schuldig aan :o ). De oorspronkelijke programmeur kent zijn code wel, maar als meerdere mensen aan code gaan werken ... Er zijn genoeg syntax checkers die default hierop een waarschuwing/foutmelding geven (waarna wij die foutmelden uit de config halen omdat het te veel werk is om alle code te herschrijven |:( ).

Het is niet fout, de standaard staat het toe, om meerdere returns te hebben; in kleine stukjes software is het niet logisch om verschillende if .. then .. else structuren in te bakken om 1 return te hebben. Vanuit foutafhandeling en safety is het echter wel best practice en wordt debugging vergemakkelijkt. Je hebt een single exit in een functie en daardoor betere controle.

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10-2025
hamsteggot schreef op maandag 29 mei 2006 @ 12:30:
Ik weet dat je moderator bent, ga er vanuit dat je veel gezien hebt, maar hier moet ik toch zeggen dat ik het heel sterk met je oneens ben. Nette functies kennen maar 1 return (single exit point). Heb al vele stukken code gereviewed in de afgelopen 10-15 jaar die door pragmatisch programmeren fouten opleveren (en ikzelf maak me daar ook schuldig aan :o ). De oorspronkelijke programmeur kent zijn code wel, maar als meerdere mensen aan code gaan werken ... Er zijn genoeg syntax checkers die default hierop een waarschuwing/foutmelding geven (waarna wij die foutmelden uit de config halen omdat het te veel werk is om alle code te herschrijven |:( ).
hier ben ik het weer niet mee eens, kijk voor de grap eens naar een message loop in een win32 applicatie, 99% van die dingen heeft meerdere return punten, niks mis mee.

trouwens, zou dit dan wel goed zijn?
PHP:
1
2
3
4
5
6
7
<?
function aap($a) {
    return $a==10?true:aap($a++);
}

echo aap(3);
?>

This message was sent on 100% recyclable electrons.


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
Dus als iedereen door rood rijdt is het goed?

Windows heeft ook niet voor niets veel fouten, ook door dit soort programmeren. Als een röntgen machine zo geprogrammeerd was, ging ik er niet vrijwillig onder liggen.

Het voorbeeld is leuk maar ook dit is dirty programmeren. Let wel; ik zeg niet dat het fout is de standaard staat het toe, maar niet netjes. Trouwens, als het zo geprogrammeerd was was de vraag niet gekomen.

Ik zou je graag eens een stukje code uit zo'n röntgen machine willen laten zien ... je schrikt je de pleuris ... echt. Wat daar allemaal gecontroleerd wordt ... ongelooflijk. Mijn eerste stukje code werd van voor naar achter afgekraakt :( . Pas later, bij het zoeken naar fouten, blijkt het gemak.

Misschien is het beter om hier een ander topic voor te openen. Titel probleem is opgelost, slotje ?

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • TheRookie
  • Registratie: December 2001
  • Niet online

TheRookie

Nu met R1200RT

Alleen 'slechte' topics krijgen een slotje; als een probleem is opgelost wordt er niet meer gereageerd en kan het topic vanzelf wegzakken :)

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 00:09

Janoz

Moderator Devschuur®

!litemod

hamsteggot schreef op maandag 29 mei 2006 @ 12:30:
Ik weet dat je moderator bent, ga er vanuit dat je veel gezien hebt, maar hier moet ik toch zeggen dat ik het heel sterk met je oneens ben.
Dat is je goed recht natuurlijk. Het rode kleurtje betekend enkel dat mensen naar mij zouden moeten luisteren wanneer ik ze op wangedrag wijs. Het is zeker geen teken van alwetendheid en het is daarom ook geen enkel probleem om het sterk met mij oneens te zijn.
Nette functies kennen maar 1 return (single exit point). Heb al vele stukken code gereviewed in de afgelopen 10-15 jaar die door pragmatisch programmeren fouten opleveren (en ikzelf maak me daar ook schuldig aan :o ). De oorspronkelijke programmeur kent zijn code wel, maar als meerdere mensen aan code gaan werken ... Er zijn genoeg syntax checkers die default hierop een waarschuwing/foutmelding geven (waarna wij die foutmelden uit de config halen omdat het te veel werk is om alle code te herschrijven |:( ).

Het is niet fout, de standaard staat het toe, om meerdere returns te hebben; in kleine stukjes software is het niet logisch om verschillende if .. then .. else structuren in te bakken om 1 return te hebben. Vanuit foutafhandeling en safety is het echter wel best practice en wordt debugging vergemakkelijkt. Je hebt een single exit in een functie en daardoor betere controle.
Ikzelf werk vooral met java. Hier krijg ik gewoon foutmeldingen (method must return foo of unreachable code). Daarnaast probeer ik mijn methodes juist zo klein mogelijk te maken.

Ik ben het verder met je eens dat je wel moet zorgen dat het overzicht behouden blijft.

Als ik echter tegen het volgende aanloop:
code:
1
2
3
4
5
6
7
8
9
10
function foo(bar) {
  //som code
  if (bar) {
    //some code
    return a;
  } else {
    //some code
    return b;
  }
}

Dan doe ik het liever op deze manier. Het aanmaken van een extra variable enkel om het result in op te slaan en deze vervolgens op 1 plek te returnen vind ik persoonlijk niet duidelijker. Ook randvoorwaarden die ik aan het begin van een methode controleer wil ik nog wel eens een return op laten leveren (mits het geen exceptions zijn) om te voorkomen dat de rest van de code te ver inspringt (zeker wanneer er meer randvoorwaarden zijn).

Ik ben het met je eens dat de programflow duidelijk moet blijven. Ik zorg er wel voor dat een return duidelijk zichtbaar blijft (desnoods met wat extra commentaar) en niet onopvallend weggemoffeld wordt.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • EnnaN
  • Registratie: September 2002
  • Laatst online: 18-02 11:31

EnnaN

Toys in the attic

verplaats je ook niet het probleem door de returnvariabele overal te setten, en die maar 1 keer te gebruiken?

op zich ben ik voor het gebruik van 1 returnplek, om de simpele reden dat je dan iig een plaats hebt waar je kan controleren wat er nou teruggestuurd wordt, dat is bij bugtacken van andere fucnties die gebruik maken van je value wel handig, maar je moet nu nog steeds in al je 'takken' kijken of je returnvariabele wel geset wordt.

sig


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 20-02 15:44
Als ik je verhaal goed begrijp geef je dus de voorkeur aan iets als:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
functie fiets($banden, $licht) {
  $result=true;
  if(!$banden->opPompen()) {
    $result=false;
  }
  if(!$licht->aan()) {
    $result=false;
  }
  if($result!==false) {
    $result='Ik fiets....';
  }

  return $result;
}


Ik zou gewoon bovenin al meteen returns geven. Nu bewaar je constant dat je eigenlijk wilt stoppen met de functie maar je laat deze toch doorlopen? De logica daarachter zie ik niet, net zomin dat ik er het overzichtelijke van zie?

  • SPee
  • Registratie: Oktober 2001
  • Laatst online: 19-02 19:02
Denk ook aan de snelheid. Als je het meteen in je code (netjes) kunt returnen, dan is je code sneller als je dit na nog x - aantal if-loops pas returned. Daarnaast, als je pas aan het eind van de functie de return geeft, weet je 100% zeker waar hij wat returned :) Echter, je wilt weten waar die data wordt toegewezen en dat is op die manier moeilijker te vinden. In jouw geval moet je dan bij alle assignments een debug item zetten, ipv bij elke return. Ik vindt die assignments moeilijker te vinden, aangezien daar geen juiste syntax highlight voor is, maar voor de return wel :)

let the past be the past.


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 00:09

Janoz

Moderator Devschuur®

!litemod

De snelheid vind ik persoonlijk een beetje een non argument. Zeker als het enkel om fixed aantal checks gaat. Dit soort micro optimalisaties zie je alleen bij embedded en game programming. Bij de rest is onderhoudbaarheid een stuk belangrijker. De kosten voor wat extra server cappaciteit zijn enorm veel lager dan het extra uurloon dat nodig is voor onderhoud.

Hiermee wil ik niet zeggen dat je niet optimaal zou moeten programmeren, echter zou je dit tot macro optimalisaties moeten houden. Met het kiezen van juiste algoritmen en datastructuren is veel meer winst te halen zonder dat je inlevert op onderhoudbaarheid.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
De meeste reacties over mijn single point of exit gaan over , veel te veel code, kan eenvoudiger of sneller. Al deze mensen zou ik eens willen zeggen: lees eens wat van Les Hatton (ja hij die ook aan de C standaard heeft meegwerkt).

Onze luiheid en ongezonde drang om snel wat te hacken (en daar doe ik ook aan mee 8) ) zorgt ervoor dat we in de afgelopen 20 jaar, met alle nieuwe programmeertalen (3e en 4e generaties) bijna niet zijn verbeterd op het gebied van fouten per 1000 regels code. Je mag denken dat dat voor een simpele PHP applicatie niet belangrijk is om netjes te programmeren ... nou vertel dat maar aan de rechter als net iemand een product van 1000 voor 100 euro heeft gekocht omdat jij weet ik veel wat had geprogrammeerd.

De discussie is verder moeilijk omdat ik denk dat je eerst meegemaakt moet hebben wat er fout gaat voordat noodzaak ook echt begrijpt (juist ook voor hack werk). Ik vergeet nooit meer dat we met 10 man een aantal dagen hebben gekeken in duizenden regels code naar een simpele fout waarbij een twee statements in een if hadden moeten staan maar waarbij geen {} werd gebruikt. De betrokken programmeur wisselde met groot gemak if's met en zonder {} af. Als er maar 1 statement was hoefde hij niet zoveel te programmeren ...

Ik betwijfel niemand zijn intelligentie maar heb te veel fouten gezien die omwille van snelheid of makkelijk programmeren zijn gemaakt. Netjes programmeren lost een groot aantal onnodige fouten op, ook de topic titel (sorry AMDinc, niet persoonlijk). Over wat is netjes kun je discussieren maar het gebruik van single exit, altijd {} bij een nieuwe context en geen berekeningen op zelfde regel als aanroep van een functie (=ook return) zijn alom bekend.

@spe, in alle jaren dat ik programmeer in safety critical embedded environments heb ik maar een paar functies gezien die te langzaam waren en die we van alle smuck hebben ontdaan. Erger nog die hebben we zelfs in assembly gecodeerd.

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • BCC
  • Registratie: Juli 2000
  • Laatst online: 20-02 19:44

BCC

Janoz schreef op maandag 29 mei 2006 @ 14:59:
De snelheid vind ik persoonlijk een beetje een non argument. Zeker als het enkel om fixed aantal checks gaat. Dit soort micro optimalisaties zie je alleen bij embedded en game programming.
Eh? Nog nooit van pre-processen gehoord? Bij complexe functies doe ik eigenlijk altijd eerst wat checks om alle onmogelijke / stupide requests eruit te vissen. Dit scheelt soms echt ontzettend, helemaal als je een paar SQL queries gebruikt binnen je functie. Ik heb dit laatst nog achteraf toegepast bij een functie die de coordianten van postcodes ophaalde en de afstand ertussen berekende. Door 't pre-processen werd alles bijna 5x zo snel. Dus weinig game of embeded.

[ Voor 17% gewijzigd door BCC op 29-05-2006 16:30 ]

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 20-02 23:46

Creepy

Tactical Espionage Splatterer

BCC schreef op maandag 29 mei 2006 @ 16:24:
[...]


Eh? Nog nooit van pre-processen gehoord? Bij complexe functies doe ik eigenlijk altijd eerst wat checks om alle onmogelijke / stupide requests eruit te vissen. Dit scheelt soms echt ontzettend, helemaal als je een paar SQL queries gebruikt binnen je functie. Ik heb dit laatst nog achteraf toegepast bij een functie die de coordianten van postcodes ophaalde en de afstand ertussen berekende. Door 't pre-processen werd alles bijna 5x zo snel. Dus weinig game of embeded.
Misschien een geval van spraakverwarring, maar Janoz heeft het over een snelheids verschil tussen het gebruik maken van een extra variabele en zo 1 exit point hebben t.o.v. meerdere exit points hebben. Het nut van input checken en bij verkeerde input stoppen lijkt me duidelijk ;)

Overigens zijn er ook talen die maar 1 exit point kunnen hebben (bijv. Pascal/Delphi). Als het voor de security / bewijsbaarheid van je code zoveel kan schelen dan vraag ik me af waarom ze zoiets bijv. niet in C# hebben gestopt.

[ Voor 12% gewijzigd door Creepy op 29-05-2006 16:36 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • BCC
  • Registratie: Juli 2000
  • Laatst online: 20-02 19:44

BCC

Creepy schreef op maandag 29 mei 2006 @ 16:34:
[...]
Misschien een geval van spraakverwarring, maar Janoz heeft het over een snelheids verschil tussen het gebruik maken van een extra variabele en zo 1 exit point hebben t.o.v. meerdere exit points hebben. Het nut van input checken en bij verkeerde input stoppen lijkt me duidelijk ;)
Ok, maar dan heb je toch een ander exit point? Ik doel hiermee nl. niet op verkeerde input, maar voor de hand liggende replies. Zoals het postcode afstandvoorbeeld, de afstand tussen A en A is 0, daar hoef je geen 2 SQL queries + coordinaten berekening op lost te laten.

Als je dus alleen maar if A==B, return 0 toevoegd heb je al een enorme speedup, wat mijninsziens het strikt gebruik maken van 1 exit point onhandig maakt. Natuurlijk kun je na de if, $result=0 assingen en dan in de else de rest van je functie doen, maar dat levert ook nogal lelijke code op.

[ Voor 19% gewijzigd door BCC op 29-05-2006 16:42 ]

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 20-02 23:46

Creepy

Tactical Espionage Splatterer

BCC schreef op maandag 29 mei 2006 @ 16:37:
[...]


Ok, maar dan heb je toch een ander exit point? Ik doel hiermee nl. niet op verkeerde input, maar voor de hand liggende replies. Zoals het postcode afstandvoorbeeld, de afstand tussen A en A is 0, daar hoef je geen 2 SQL queries + coordinaten berekening op lost te laten.
Ik heb het over het volgende verschil:
code:
1
2
3
4
5
if (a = b) {
 return 0;
}

return (//berekening hier);

t.o.v.
code:
1
2
3
4
5
6
if (a = b) {
  result = 0;
} else {
  result = (//berekening hier);
}
return result;

Qua leesbaarheid vindt ik zelf de eerste iets duidelijker. Qua snelheid gaat het nagenoeg niets uitmaken (1 jump extra).
Dat je dit soort checks (if a = a) uitvoert leek mij voor de hand liggend ;)

[ Voor 7% gewijzigd door Creepy op 29-05-2006 16:44 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • BCC
  • Registratie: Juli 2000
  • Laatst online: 20-02 19:44

BCC

Ja, dat is logisch, maar dat is ook niet het onderwerp van de discussie. Zie het stuk van DJLUC:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
functie fiets($banden, $licht) {
  $result=true;

  if(!$banden->opPompen()) {
    $result=false;
  }
  if(!$licht->aan()) {
    $result=false;
  }
  if($result!==false) {
    $result='Ik fiets....';
  }

  return $result;
}


Hier zullen meerdere exit points voor een speedup zorgen. Als deze functie een stukje complexer is, een hele grote speedup..
Alternatief is alles nesten, zoals jij voorstelt. Dan scheelt het idd maar een paar jumps, maar dat levert wat mij betreft onleesbare code op..

[ Voor 97% gewijzigd door BCC op 29-05-2006 17:02 ]

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


  • bartje321
  • Registratie: November 2003
  • Laatst online: 19-02 16:28
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
functie fiets($banden, $licht) {
  $result=true;

  if(!$banden->opPompen()) {
    $result=false;
  }
  else if(!$licht->aan()) {
    $result=false;
  }
  else if($result!==false) {
    $result='Ik fiets....';
  }

  return $result;
}

else if''jes O-)

@hamsteggot: wedden dat je ook tegen goto''s bent :) (en ik geef je groot gelijk)

  • BCC
  • Registratie: Juli 2000
  • Laatst online: 20-02 19:44

BCC

else if''jes O-)
Dat helpt dus niets.. stel dat (!$licht->aan()) 5 seconden duurt. Dan had je beter alvast kunnen returnen.

[ Voor 14% gewijzigd door BCC op 29-05-2006 17:12 ]

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
BCC schreef op maandag 29 mei 2006 @ 17:12:
[...]


Dat helpt dus niets.. stel dat (!$licht->aan()) 5 seconden duurt. Dan had je beter alvast kunnen returnen.
Als de eerste if conditie true oplevert wordt het else gedeelte toch echt niet ge-evalueerd. ;)

Maar goed, dit topic is nu meer een coding style topic geworden...

{signature}


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
En dit voorbeeld bewijst alweer exact mijn punt. Er wordt alleen iets gedaan als het goed gaat, wat als het fout gaat? Door single exit wordt je verplicht daarover na te denken. Verder mag je nooit types mixen (eerst boolean, dan string). Het is niet een wedstrijd hoe schrijf ik zo min mogelijke ascii karakters.

De effectieve snelheidswinst/verlies is in miliseconden bijna niet uit te drukken, een variabele assignement is 1 opcode, deze variabelen worden meestal in registers geoptimaliseerd wat in totaal 1 opcode is. Er zijn maar weinig programmeurs die zich hier zorgen over hoeven te maken. De huidige compilers optimaliseren zo verschrikkelijk goed dat 98% van de programmeurs daar niet de echte snelheidswinst hoeft te zoeken. Kijk liever naar de echte functionaliteit. (gebruik van eigen tracing/debugging is natuurlijk wel een behoorlijke belasting en is misschien wel handig om die via macro's uit te kunnen zetten zodat die ook niet in de eind code terecht komt).

Her argument duidelijkheid bij snelle code vind ik persoonlijk een non-argument. Als jij bij grote functies zeker weet dat er maar 1 exit is, geeft dat een beter beeld dan dat er verschillende exits zijn. Van QAC weet ik nog de message: completely untestable!

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • Icelus
  • Registratie: Januari 2004
  • Niet online
Creepy schreef op maandag 29 mei 2006 @ 16:34:
[...]

Overigens zijn er ook talen die maar 1 exit point kunnen hebben (bijv. Pascal/Delphi).
In Delphi is het ook mogelijk (misschien iets omslachtiger):
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function fun(x:integer):integer;
begin
     if ( x < 0 ) then begin
       result := -1;
       exit;
     end;

     if ( x = 0 ) then begin
       result := 0;
       exit;
     end;

     result := 1;
end;

Developer Accused Of Unreadable Code Refuses To Comment


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 20-02 23:46

Creepy

Tactical Espionage Splatterer

@Icelus: Hmmja, dat vindt ik dan weer meer misbruik i.p.v. gebruik van een taal.

@hamsteggot: ook met meerdere exit points zul je toch echt moeten nadenken over foutafhandeling. Mijn inziens zit daar nu geen verschil in als je gebruikt maakt van 1 of meerdere exit points.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
Tuurlijk, alleen door een single exit wordt je meer gedwongen daar over na te denken, of anders gezegd je vergeet het minder makkelijk als dat je 10 exits hebt. Daarnaast kun je bij een single exit uniformere meldingen geven en dat bespaart een lap aan code (als je het hebt over snelheidswinst).

[ Voor 30% gewijzigd door hamsteg op 29-05-2006 18:06 ]

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • bartje321
  • Registratie: November 2003
  • Laatst online: 19-02 16:28
je kunt natuurlijk ook valsspelen :)

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
char functie(int parameter){
    if(parameter == 1){
        return 'a';
    }else if(parameter == 2){
        return 'b';     
    }else if(parameter == 3){
        return 'c';     
    }
    return 'd';         
}

char prefunctie(int parameter){
    char result = functie(parameter);
    //whie, single exit point
    return result;
}

[ Voor 13% gewijzigd door bartje321 op 29-05-2006 19:35 ]


  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 10:19
voorbeelden als

code:
1
2
if a return b
return c


vind ik veel fijner en overzichtelijker dan dingen als

code:
1
2
3
4
if a result = b
else result = c

return result


Kwestie van smaak denk ik dan.

[ Voor 92% gewijzigd door Grijze Vos op 30-05-2006 00:37 ]

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
Dat verhaal met die code snap ik niet want ik heb geen eigen code geschreven, ik heb alleen een stukje code uitgebreid om de oorspronkelijke vraag te beantwoorden
Ik heb een probleem waarbij een recursieve functie een boolean waarde moet returnen ... Deze functie returned helemaal niks.
en de geschreven oplossing doet dit wel. Afhankelijk van de functionaliteit kun je ervoor kiezen om die false als chain terug te geven.

Met zulke simpele, niets zeggende, stukjes code heb je gelijk. Tuurlijk ziet dat er beter uit, maar daarom is het nog niet goed. Ik breid jouw code uit met nog een if een nette foutafhandeling en dan kun je je al afvragen wat netter is:
C:
1
2
3
4
5
6
7
8
9
10
11
if (a==true) 
{
  er is iets fout met xa;
  return xa;
}
if (b==true)
{
  er is iets fout met xb;
  return xb;
}
return xc;


Wat een veilig programmeur zou doen:
C:
1
2
3
4
5
6
7
8
retval = initvalue
if ( a == true )
  retval = xa;
if ( b == true )
  retval = xb;
if ( retval != initvalue )
  er is iets fout met retval;
return retval;

Moet je voor het returnen ook nog dingen opruimen dan wint mijn constuctie al heel snel in code omvang. Je moet kiezen voor generieke structuren en niet wat volgens jou op dat moment mooi en sneller is. Inconsequentie zorgt voor fouten.

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12-2025
hamsteggot schreef op maandag 29 mei 2006 @ 20:30:
Regelmatig zie ik stukje code voorbij flitsen die mijn tenen doen krommen. Sommigen zijn nodig voor eenvoudige uitleg zonder smuk maar anderen zijn zo uit code ge-cut en paste. Soms kan ik mij niet inhouden en moet ik daar wat van zeggen. Vandaag was het weer zover ... single point of exit :)
Ben gelukkig niet de enige die dat zo'n tenenkrommend idee vindt. Het enige resultaat is dat je dan code transformeert van
C++:
1
2
3
4
5
6
T foo() {
  if (bar())
     return a;
  else
     return b;
}
naar
C++:
1
2
3
4
5
6
7
8
T foo() {
  T return_value;
  if (bar())
     return_value = a;
  else
     return_value = b;
  return return_value;
}

Nu is dat bij zo'n simpel voorbeeld nog wel te zien dat het correct is, maar bij complexere functies heb je dus het risico dat mensen per ongeluk twee keer assignen aan return_value, of 0 keer. Gebruik gewoon return als je return bedoelt. Dan is de compiler je vriend; 0 of 2 objecten returnen kan simpelweg niet. En je code is nog simpeler en effectiever ook.

[edit]
Je hebt duidelijk nog meer WTFs. if (a==true) :) Wie dat verzonnen heeft 8)7 . Ik bedoel, dat is precies net zo logisch als ((a==true)==true). Als a een boolean is, dan is (a==true) dezelfde, en ((a==true)==true) etcetera ook. Je kunt natuurlijk ook (a!=false) schrijven, of (a||a).

Geen functieaanroepen is argumentenlijsten is ook al zo'n typische ik-snap-de-taal-niet statement. D'r zijn altijd mensen die denken dat drukaf(2*b+1) een slecht idee is (is't ook, Nederlands gebruiken voor identifiers) en het ene beter idee vinden om te schrijven
code:
1
2
temp = 2*b+1;
print(temp);

Om een of andere reden realiseren dat soort mensen zich dan niet dat de +functie toch echt als argument het resultaat van de *functie heeft. Maar ja, dat hebben ze al op de basisschool geleerd, dus dat mag dan wel. 8)7

[ Voor 30% gewijzigd door MSalters op 29-05-2006 20:47 ]

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • whoami
  • Registratie: December 2000
  • Laatst online: 20-02 21:53
[quote]hamsteggot schreef op maandag 29 mei 2006 @ 20:30:
• Single point of exit (dus maar 1 return statement)

Een Single point of exit vind ik niet altijd even 'fail safe'. Voor eenvoudige methods kan dat wel handig zijn, maar in complexere methods, kan het hebben van 'guard clauses' best wel handig zijn.

[quote]
• Altijd booleans checken tegen hun waarde (a==true)
Dit doe ik zelf ook altijd, maar is dat iets waardoor je code beter van wordt ? Ik bedoel, is dat echt veiliger ? Ik doe het zelf altijd gewoon zo omdat ik het leesbaarder vind. Maar dat is dus subjectief.
[quote]
• Altijd nieuwe context in {} zetten, ook bij 1 statementDoe ik ook en vind ik ook beter en duidelijker.

Als je echt fail-safe wilt programmeren, dan is het niet zozeer de 'stijl' van programmeren die echt het belangrijkst is (het is wel belangrijk, maar, het belet je niet van het maken van fouten, het verminderd ze wel), maar dan is het imho belangrijker dat je een aantal goede test-cases hebt. Een automated test suite dus, die je toelaat om je evt gedane veranderingen (refactorings / uitbreidingen) te testen, en controleren of de bestaande functionaliteit nog juist werkt.

https://fgheysels.github.io/


  • newpegasus
  • Registratie: Juni 2003
  • Laatst online: 13-03-2022

newpegasus

Hertog

Functies nooit aanroepen met berekeningen in de parameter list (drukaf(2*b+1);) Hier ben ik het niet helemaal mee eens: eenvoudige berekeneningen zoals in jouw voorbeeld lijken mij geen probleem? Waarom zou je voor deze berekening een aparte variabele gebruiken, dat maakt voor mij de leesbaarheid niet beter. Zo ben ik bezig met een soort bordspel in Java met een tweedimensionale array van integers. (kaart-coordinaten) Dan vind ik dit:

Java:
1
2
3
4
5
private int[][] board;

if (board[x+2][y-2] instanceof Farm){
  //doe iets
}


toch beter leesbaar dan dit:
Java:
1
2
3
4
5
6
7
8
private int[][] board;

tempx = x+2;
tempy = y-2;

if (board[tempx][tempy] instanceof Farm){
  //doe iets
}


Of bedoel je dat alleen wanneer er een functie-aanroep in de parameterlijst voorkomt, want dan kan ik me er nog iets bij voorstellen...

GuitarFacts | Last.fm | Google Zoekmachine Optimalisatie


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
@MSalters, ben ik niet helemaal met je eens. Het is hoofdzakelijk een kwestie van gewenning (na vier jaar weet ik niet beter) wat een voordeel is, is dat de debug trree behoorlijk eenvoudiger wordt en dat cleanup en error handling op deze manier alleen aan het einde van een functie hoeven worden uitgevoerd.
En je code is nog simpeler en effectiever ook.
Dat was ook jaren lang mijn tegenargument. Na vier jaar ben ik om. Assembly code heeft mij bij praktijk implementaties (en niet deze simpele voorbeelden) laten zien dat het over de linie niets uitmaakt. Het is afhankelijk van wat er gebeurt voor de return. Huidige compilers zijn zo verschikkelijk goed dat het verlies in snelheid / hoeveelheid code te minimaliseren is voor de overgrote hoeveelheid van applicaties. In al mijn jaren heb ik nog maar een handvol functies gezien waar dit bewezen werd (en die in assembly zijn herschreven).

Stel dat we het hier over eens zijn en we staan dit voor de hobby toe, hoe sta je dan tegenover een return in een loop context?

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
@whoami
Dit doe ik zelf ook altijd, maar is dat iets waardoor je code beter van wordt ? Ik bedoel, is dat echt veiliger ? Ik doe het zelf altijd gewoon zo omdat ik het leesbaarder vind. Maar dat is dus subjectief
in c voorkomt dit grove fouten. Een goede compiler geeft different types als dit bij een assignment of conditie wordt gebruikt. Nog mooier is het om de constante voor de variabele te zetten; true == a. Als er een '=' vergeten wordt zal de compiler klagen over constant can not be assigned a value.
Als je echt fail-safe wilt programmeren, dan is het niet zozeer de 'stijl' van programmeren die echt het belangrijkst is (het is wel belangrijk, maar, het belet je niet van het maken van fouten, het verminderd ze wel), maar dan is het imho belangrijker dat je een aantal goede test-cases hebt. Een automated test suite dus, die je toelaat om je evt gedane veranderingen (refactorings / uitbreidingen) te testen, en controleren of de bestaande functionaliteit nog juist werkt.
Na 15 jaar professioneel programmeren ben ik ook hier niet meer mee eens. In den beginne riep ik dit ook test suites kunnen alles ... dacht ik. Maar als je ziet in de statistieken waar de grootste hoeveelheid niet functionele fouten direct te vinden is, is dat in de stijl van programmeren. Bij duizenden regels code, kun je niet alles meer testen. Code reviews worden voor mij een steeds zwaarder punt om de echte winst te pakken op niet functionele fouten en een duidelijke stijl is dan nodig om met elkaar 1 soort code op te leveren.

[ Voor 64% gewijzigd door hamsteg op 29-05-2006 21:06 ]

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


Verwijderd

Ik ben het op geen enkel punt met je eens. Bovendien verklaar je niet eens wat er mis mee is of waarom het anders zou moeten. Syntax-purisme dat weinig hout snijdt en vooral een kwestie van smaak is.

Single point of exit (dus maar 1 return statement)
Meestal levert dit spaghetti-code op, overbodige flags en zelfs goto's worden hier aangetroffen

Altijd booleans checken tegen hun waarde (a==true)
Het fijne van booleans is juist dat je er syntactisch leesbare constructies mee kan maken. Maar er zijn zelfs puristen die (true==a) prefereren omdat je dan geen ==/= errors kan maken. Yuk.

Altijd nieuwe context in {} zetten, ook bij 1 statement
Waarom? 'if (somepointer) somepointer->func();' bijv. zal zelden veranderen en dat helemaal uitschrijven levert niks op kwa leesbaarheid, integendeel.

Nooit meerder statements op 1 regel (for loop is uitzondering, ++=1 statement)
Er zijn wel meer uitzonderingen, zie bovenstaand

Functies nooit aanroepen met berekeningen in de parameter list (drukaf(2*b+1);)
Nogmaals, waarom niet? Zo werken functies, je kan als parameter een andere functie geven en ik zou niet weten waarom je daar geen gebruik van zou maken.

else...if constructies die meer als twee keer genest zijn, verbieden.
Soms is er geen alternatief, of levert zo'n alternatief dezelfde of nog ergere spaghetti op.

Verwijderd

Misschien is het ook eens verstandig om te bedenken wat de oorzaak van dergelijke fouten is.
Een van de betere boeken op dit gebied vind ik persoonlijk 'Secure coding, principles & practices' uitgegeven door O'Reilly. In het boek worden de volgende 'good practices' beschreven:
  • Inform yourself
    - Follow vulnerability discussions
    - Read books and papers
    - Explore open source software
  • Handle data with caution
    - Cleanse data (check data op kwaadaardige inhoud, vb SQLinjections)
    - Perform bounds checking
    - Check configuration files
    - Check command-line parameters
    - Don't trust web URL's
    - Check environment variables
    - Set valid initial values for data
  • Reuse good code whenever practicable
  • Use review processes if possible (laat je collega ook eens naar de code kijken)
Persoonlijk wil ik nog een item toevoegen aan het lijst:
  • Maak gebruik van standaarden
Het schrijven van bijvoorbeeld een eigen configuratie bestand formaat is leuk. Maar een reeds, door veel mensen gebruikte, standaard (en dus door veel gebruikers getest), verdiend toch de aanbeveling.

Rest nog de vraag wanneer je secure coding moet gaan toepassen.
Persoonlijk vind ik dat de IT project manager, met hopelijk een goede kennis van ICT, dit moet signaleren en hiervoor budget voor moet creeeren. Je kunt niet van een programmeur verwachten veilige code met een minimaal budget te schrijven. Wil (hogere) management geen budget stellen zijn er denk ik 1001 voorbeelden van de gevolgen te vinden.

Waar ik benieuwd naar ben (mogelijk beetje off-topic), Tweakers bij de grotere bedrijven, zijn er inmiddels interne richtlijnen voor source code kwaliteit en worden deze ook strikt gebruikt?

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 20-02 17:44

Robtimus

me Robtimus no like you

hamsteggot schreef op maandag 29 mei 2006 @ 20:30:
Single point of exit (dus maar 1 return statement)
Alsjeblieft niet zeg. Stel je het volgende stuk code voor:
Java:
1
2
3
4
5
6
7
8
9
10
public void doSomething(int a) {
    if (test1(a)) {
        return 1;
    }
    if (test2(a)) {
        return 2;
    }
    // andere code
    return 0;
}
Dit zou dan als volgt moeten:
Java:
1
2
3
4
5
6
7
8
9
10
11
public void doSomething(int a) {
    int ret = 0;
    if (test1(a)) {
        ret = 1;
    } else if (test2(a)) {
        ret = 2;
    }
    // andere code, met mss veel else if's of nog erger: geneste if's
    ret = 0;
    return ret;
}
Geef mij maar multiple returns. Mocht er bepaalde code altijd moeten worden uitgevoerd vlak voor returnen dan kent Java nog altijd try-finally.
Altijd booleans checken tegen hun waarde (a==true)
En dan natuurlijk de fout maken dat je een = vergeet en een assignment doet gevolgd door de test:
Java:
1
2
3
if (a = true) {
    // dit wordt altijd uitgevoerd
}
Altijd nieuwe context in {} zetten, ook bij 1 statement
Mee eens. Altijd handig om snel debug statements toe te kunnen voegen zonder dat je code opeens stuk is omdat je je haakjes bent vergeten.
Nooit meerder statements op 1 regel (for loop is uitzondering, ++=1 statement)
Mee eens, dat maakt het alleen maar onleesbaarder.
Functies nooit aanroepen met berekeningen in de parameter list (drukaf(2*b+1);)
Please... Wat is er zo ingewikkeld aan 2*b+1? Dat leer je op de basisschool (als je weet wat b is tenminste ;)). Als er onduidelijkheden zijn: zet haakjes.
Eentje die er op lijkt:
Geen assignments in functie aanroepen. Dus geen print(i = 2*++i - 5*i++);
Dit is wel onnodig verwarrend en onduidelijk.
else...if constructies die meer als twee keer genest zijn, verbieden.
Daar ontkom je soms niet aan. En om dan meteen hele functies te gaan schrijven voor 1 enkele if statement is ook weer zo onzinnig. Wel ben ik het met je eens dat blocks, niet alleen voor if, niet te diep genest moeten worden. Maar refactoren alleen maar om de nesting laag te houden, nee, daar doe ik niet aan. Iets moet IMHO alleen een function worden als het ook echt specifieke functionaliteit biedt.
(enterance/exit tracing van een functie)
Que??

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 20-02 09:23

LauPro

Prof Mierenneuke®

Vanwege je werk begrijp ik dat je enorm veilige code moet schrijven. De meeste security leaks die ik heb gezien in projecten bestaan vaak over bugs die zich over meerdere functies spreiden. Of bijvoorbeeld een te sumiere controle bij een functie waardoor er verkeerde data in de database terecht komt.
hamsteggot schreef op maandag 29 mei 2006 @ 20:30:
• Single point of exit (dus maar 1 return statement)
Dat ligt aan de functie, als de functie bijvoorbeeld onderdeel is van een template-parser en bijvoorbeeld de juiste waardes van template-variabelen retourneert lijkt me per variabele een return wenselijk om de snelheid erin te houden. Alternatief is dat je een variabele vult en die aan het einde van de functie retourneert, echter kan er onderweg wat mis gaan natuurlijk.
• Altijd booleans checken tegen hun waarde (a==true)
Neem aan dat je het volgende wil voorkomen?
PHP:
1
if ($a) { ... }
Als je de bovenstaande constructie niet vertrouwt dan vraag ik me af waarom je wel vertrouwen hebt in de compiler/parser?
• Altijd nieuwe context in {} zetten, ook bij 1 statement
• Nooit meerder statements op 1 regel (for loop is uitzondering, ++=1 statement)
• Functies nooit aanroepen met berekeningen in de parameter list (drukaf(2*b+1);)
Bovenstaande lijkt me ten goede moeten komen van de readability? Hiermee probeer je dus mogelijk risico mbt leesfouten van de programmeur te voorkomen?
• else...if constructies die meer als twee keer genest zijn, verbieden.
Wat gebruik je als alternatief? Een boolean die eerst true is en als een conditie niet voldaan wordt false raakt? Of alles in losse functies stoppen?
• (enterance/exit tracing van een functie)
[/list][/quote]Hiervan lijkt me ook het bevorderen van de debuggen voor de programmeur, maar hier bestaan toch debuggers voor?

Overall gezien zijn je richtlijnen volgens mij men name bedoeld om (lees)fouten door de programmeur te voorkomen. Als je hier alleen maar rekening mee houdt dan ben je denk ik een beetje naïef. Er zijn veel meer aspecten waarbij in mijn ogen de usability voor de ontwikkelaar een veel lagere prioriteit heeft.

Denk bijvoorbeeld aan geparametriseerde databasetoegang, het gebruik van transacties, globale unieke identificatoren maar vooral ook het client/server beveiligingsmodel. Beveiliging op client-niveau is fout en in mijn ogen ook naïef te noemen. Je mag best functies afschermen bij clients echter dit mag nooit het criterium zijn of een functie uitgevoerd mag worden wel/niet.

Nog los van de applicatie moet je ook kijken naar het platform. Een Java/C++-applicatie die direct een verbinding van een client met de databaseserver op zet is bijvoorbeeld beveiligingstechnisch gezien al kwetsbaarder dan een webinterface waarbij de databaseserver niet van 'buitenaf' bereikbaar is. Je moet kijken hoeveel impact een man-in-the-middel-attack kan hebben op je applicatie (zijn de rechten in de database/functies voor de gebruikers goed afgeschemd). Bij een webbased-applicatie heb je te maken met veel externe factoren, de browser, DNS, diverse plugins welke ook allemaal stuk voor stuk potentiële beveiligingsrisico's vormen.

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
@MIIM, Ik heb een lange tijd geprogrammeerd in grote teams en geloof mij dat naarmate de code moeilijker wordt, juist dit soort constructies sterker zijn en juist spagettie tegengaan. Probeer maar eens een functie te debuggen met 10 exits op verschillende plaatsen die elk vlak daarvoor ook nog wat opruimen (redundante code). Wat jiji YUK vindt, vind ik geen argument. Zeker de (true == value) constructie wordt door bedrijven verplicht opgelegd omdat je er twee mogelijk fouten mee kunt afvangen. Dat jij (of ik) het niet mooi vindt kan zijn maar de functionaliteit/gedachte is voor mij doorslagevend.

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • Juup
  • Registratie: Februari 2000
  • Niet online
  • Single point of exit (dus maar 1 return statement)
Eens muv hele kleine functies. Als ze groter groeien, moet je het refactoren naar 1 return
  • Altijd booleans checken tegen hun waarde (a==true)
Oneens, je reinste waanzin, tenzij je per byte betaald wordt
  • Altijd nieuwe context in {} zetten, ook bij 1 statement
Eens
  • Nooit meerder statements op 1 regel (for loop is uitzondering, ++=1 statement)
Eens
  • Functies nooit aanroepen met berekeningen in de parameter list (drukaf(2*b+1);)
Eens, is lelijk en wazig.
  • else...if constructies die meer als twee keer genest zijn, verbieden.
Oneens. Soms is het nodig anders worden je "else if ()"'s wel heeeeeel lang
  • (enterance/exit tracing van een functie)
Geen idee wat je bedoelt.

[ Voor 8% gewijzigd door Juup op 29-05-2006 21:28 ]

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
@LauPro. Sorry maar het ging niet om het schrijven van goede functionaliteit ... het gaat alleen om failure safe code schrijven.
Overall gezien zijn je richtlijnen volgens mij men name bedoeld om (lees)fouten door de programmeur te voorkomen. Als je hier alleen maar rekening mee houdt dan ben je denk ik een beetje naïef
hmm, ik probeerde juist de scope beperkt te houden. Dat is niet naief maar juist bedoeld om deze explosie te voorkomen. We kunnen ook een topic starten over modelleringmethoden en technieken, architectuur, verantwoordelijkheden binnen een projectenteam, businesscases, bedrijfspolitiek en fylosofie etc. etc. allemaal van invloed op de uiteindelijk functionaliteit van de applicatie... ik wilde het beperkt houden tot code schrijven -- de laagste tak van het 'V' model, schrijven en code review.

Met betrekking tot boolean compare en PHP heb je gelijk ... PHP heeft goed geken naar C en een eigen type gemaakt, dit geldt echter niet voor alle talen.

[ Voor 4% gewijzigd door hamsteg op 29-05-2006 21:37 ]

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • whoami
  • Registratie: December 2000
  • Laatst online: 20-02 21:53
En dan natuurlijk de fout maken dat je een = vergeet en een assignment doet gevolgd door de test:
Bepaalde talen / compilers gaan daarop klagen. :)

https://fgheysels.github.io/


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
@jaaap, pfieuw ik had al het gevoel de advocaat van de duivel te zijn. })

Het is mijn ervaring dat [else .. if .. else .. if] vaak efficienter herschreven kan worden met behulp van switch case of arrays (twee of meer die langs elkaar liggen). Natuurlijk zijn er uitzonderingen maar vaak is het een kwestie van niet goed nadenken en gewoon beginnen.

voor booleans checking zie mijn eerdere postings. PHP heefft het eindelijk goed opgelost.

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

hamsteggot schreef op maandag 29 mei 2006 @ 20:02:
Wat een veilig programmeur zou doen:
C:
1
2
3
4
5
6
7
8
retval = initvalue
if ( a == true )
  retval = xa;
if ( b == true )
  retval = xb;
if ( retval != initvalue )
  er is iets fout met retval;
return retval;
Nee, een veilige programmeur zou true == a schrijven ipv andersom in C-achtige talen (of eigenlijk gewoon a, aangezien het een boolean is, maar voor een check tegen een rvalue is het handig om de rvalue links te zetten, zodat je niet per ongeluk een assignment doet).
Moet je voor het returnen ook nog dingen opruimen dan wint mijn constuctie al heel snel in code omvang. Je moet kiezen voor generieke structuren en niet wat volgens jou op dat moment mooi en sneller is. Inconsequentie zorgt voor fouten.
Tja, maar C is nogal lomp wat dat betreft. In C++ doe je dat met destructors en in C# met een IDisposable pattern (using). Try/finally is ook wel handig in dat opzicht. En dan heb je dat hele laatste probleem niet meer. Wat ik van jou code vooral vervelend vind is dat je niet goed kunt zien wat de paden nou eigenlijk zijn. Vooral met veel if-structuren in een functie kun je al snel de mist in gaan als je iets vergeet te controleren. Dat probleem zou je met meerdere returns niet hebben omdat het duidelijk is dat de code niet verder gaat na de return.

Voorbeeld:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void MyClass::RunStateMachine()
{
    if (m_state == StateFirst)
    {
        // bladiebla
        m_state = StateSecond;
    }

    if (m_state == StateSecond)
    {
        // yadda yadda yadda
        m_state = StateThird;
    }

    // etc
}

Probleem: alle states worden uitgevoerd, omdat je de else vergeten bent (gebeurt vrij vaak imho). Met een return heb je dat probleem niet. En voor de slimmeriken die gaan zeggen dat je hier een switch voor kan gebruiken: helaas, dat lukt niet als m_state geen integral type is ;)

En dit nog even naast het feit dat je in sommige talen niet eens een reassignment kunt doen (zoals in C++ met bepaalde classes die je alleen kunt initializen met een constructor). Dan kán het dus gewoon niet eens.

Trouwens, voor iemand die zo idealistisch bezig is vraag ik me af waarom je überhaupt in C programmeert ;)

[ Voor 10% gewijzigd door .oisyn op 29-05-2006 21:48 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hoi hamsteggot, het is handig als je dit vantevoren eerst even met de mods bespreekt. Nu lopen er namelijk 2 discussies door elkaar, terwijl de eerste het makkelijkst gewoon afgesplitsts had kunnen worden. Deze gaat even dicht

(oh, en als je een topiclink neerzet doe dat dan zonder de url tag, dan maakt de forumsoftware er zelf een mooi linkje van ;))

.edit: ziezo.

[ Voor 3% gewijzigd door .oisyn op 29-05-2006 21:41 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
Trouwens, voor iemand die zo idealistisch bezig is vraag ik me af waarom je überhaupt in C programmeert
Idealen op dit gebied heb ik al lang niet meer, eerder des-illusies :'(
Het nadeel van C is ook zijn kracht. De eenvoud maakt het makkelijk om relatief snelle code te maken die op embedded systemen goed en snel functioneert. Probeer dat maar eens met een 4de genratie taal. PHP biedt vanuit die optiek enorm veel verbeteringen ten opzicht van C maar wordt als compiler niet ondersteunt voor de verschillende hardware platformen. De gegeven lijst was bedoeld als voorbeeld maar wordt nu gebruik om mij af te maken. Als iedereen zich zou houden aan zijn eigen uitspraken zouden er nooit programmmeerfouten bestaan ... maare waarom gaat er dan zoveel fout?

Zoals je het hier neerlegd, heb je gelijk. Maar zoals ik al eerder heb aangegeven probeer ik te kijken wat voor ons als thuis-programmeurs een must is. Jouw voorbeeld kan ik ook counteren met iets wat ik gisteren ook nog weer zag. Gisteren heb ik nog de volgende soort code gezien voor het tonen van een aantal strings en daarbij wat speciale acties, voor de eenvoud heb hier als voorbeeld hex codes gebruikt:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void print_hex_waarde(int waarde)
{
  if( waarde == 0 )
    if( true == bScreen )
      printf("1");
    else
      beep(0+1);
    return;
  if( waarde == 1 )
    if( true == bScreen )
      printf("1");
    else
      beep(1+1);
    return;
  ...
  if( waarde == 15 )
    if( true == bScreen )
      printf("F");
    else
      beep(15+1);
    return;
}

void mijn_hex_print(int waarde)
{
  char Hex[HexMaxNumbers]  = { '1', '2', ...'F' }; 
  if( true == bScreen )
    printf("%c", Hex[waarde]);
  else
    beep( waarde + 1);
}

Loop ik nog even voorbij aan het controleren van 'waarde'. Het lijkt heel simpel maar als de lijst met mogelijkheden langzaam groeit (en niet beperkt blijft tot 16), zie je het niet zo duidelijk meer. Veel return statements zijn vaak een teken dat de code inefficient is, er zijn altijd uitzonderingen.

:o Had net geleerd dat een topic nooit zomaar dicht gaat, vond dit wel een sjieke oplossing omdat de titel al lang niet meer de lading dekte ... zal volgende keer lief zijn.

[ Voor 41% gewijzigd door hamsteg op 29-05-2006 22:19 ]

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

hamsteggot schreef op maandag 29 mei 2006 @ 21:53:
Het nadeel van C is ook zijn kracht. De eenvoud maakt het makkelijk om relatief snelle code te maken die op embedded systemen goed en snel functioneert. Probeer dat maar eens met een 4de genratie taal.
Sure, C heeft z'n voordelen, maar die vallen vaak in het niet bij de toegevoegde features van C++. En die werkt ook prima op embedded systemen, hoewel je wellicht wilt compileren met exceptions uitgeschakeld (de meeste compilers hebben hier wel functionaliteit voor). En comeau kan je C++ code mooi omzetten naar C code zodat je het ook kunt gebruiken met de meest exotische C compilers :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
Het belangrijkste nadeel van 4de generatie talen is de onmogelijkheid om het gedrag van het systeem te voorspellen aan de hand van de code. De uitgebreide, onder water, functionaliteit maken voorspelbaarheid van executie een echte crime, gewoonweg onmogelijk. Een simpel voorbeeld is garbage collection, een machtig feature, maar ook een die willekeurig toeslaat. Oh, en ik weet dat je garbage collection kunt uitschakelen maar dat betekent ook dat je de programmeurs moet opdragen hun geheugen expliciet vrij te maken, weg mooi feature. Constructoren en destructoren, ze lijken simpel en werken goed maar als het op voorspelbaarheid van executie van code aankomt ... wordt het toch al minder.

Wat we tegenwoordig veel doen en ook zien is dat op de systeemkritische elementen plat C draait en de toepassingslagen Java/C++. Het goede van elk gebruiken :> . Maar juist bij gebruik van 2 (of meerdere!) talen wordt een eenduidige overkoepelende stuctuur heel belangrijk, ook in coding conventions.

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

C++ kent geen garbage collection ;) (en ik zou het ook nauwelijks een 4e generatie taal willen noemen). En het is ook niet zo dat C++ standaard onvoorspelbaar is, het mooie ervan is nou juist dat je het kunt gebruiken zoals je zelf wilt. En zeker als je safe code wilt schrijven (waar deze hele topic over gaat) zou ik C++ boven C verkiezen, omdat je er dan voor kunt zorgen dat je a) geen leaks hebt, b) kunt zorgen dat je nooit buiten je buffers schrijft, en c) alle resources gewoon opgeruimd worden door destructors (resource acquisition is initialization). Bovendien heb je het nu wel heel erg over theoretische gevallen die maar een fractie zijn van de totale softwaredevelopment, en dus nauwelijks interessant in een discussie imho :)

[ Voor 86% gewijzigd door .oisyn op 29-05-2006 22:55 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

• Single point of exit (dus maar 1 return statement)
Dit doe ik wel vaak, bij sommige functies gebruik ik er meerdere, maar probeer het te voorkomen. Ik maak altijd netjes een $ret aan, waar mijn return waarde in zit.
• Altijd booleans checken tegen hun waarde (a==true)
Eens
• Altijd nieuwe context in {} zetten, ook bij 1 statement
Opzich heb je wel gelijk, maar als een functie slechts 4 of 5 regels bevat dan doe ik dit niet. Bij grotere functies doe ik dit weer wel ivm duidelijkheid en overzicht.
• Nooit meerder statements op 1 regel (for loop is uitzondering, ++=1 statement)
Eens
• Functies nooit aanroepen met berekeningen in de parameter list (drukaf(2*b+1);)
Over het algemeen los ik dit op een andere manier op, het kost me weer geheugen om een string op te slaan.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
functie a($b)
{
  //meer code hierzo, blaat.....
  //asdasdasdad

  return blaat( //--------START-C
        (4*8), //commentje
        asc($b), //meer comments blaat
        anderfunctie( //en nou nog dit berekenen
                8*2, //dit is voor de 1e dinges
                2*2 //en dit de 2e
        )
  );//-----END-C
}

Dit scheelt echt bergen zooi die je anders weer moet opruimen. Gezien ik veel met PHP-CLI doe moet ik dit wel doen (PHP Daemons, etc ;) ). Ik kan niet continu alles in de gaten houden qua netheid en opruiming.

• else...if constructies die meer als twee keer genest zijn, verbieden.
Why dat?
• enterance/exit tracing van een functie
Opzich wel handig, maar dat doe ik zelf wel even schrijven dmv een enkele echo (als er iets op z'n bek gaat). Om nou te zeggen dat ik me hier ooit mee bezig houd, nee dat niet. Maar dat kan liggen omdat ik een hobby programmeur ben.
Janoz schreef op maandag 29 mei 2006 @ 14:59:
De snelheid vind ik persoonlijk een beetje een non argument. Zeker als het enkel om fixed aantal checks gaat. Dit soort micro optimalisaties zie je alleen bij embedded en game programming.
/me jaagt Janoz het bos in, kst!

Hoe goed kon jij werken op een 386? Alles werkte toch perfect? Nou worden de computers steeds sneller en sneller, maar qua werktijd/opstarttijd word het er nogsteeds niet beter op. Zoek het verschil tussen een 386 (25MHz) met DOS 6.22 en een P4 alla 3GHz met Windows XP / Vista. De 386 start nog sneller op dan de Windows bak. En nee, dat ligt niet aan Windows, want een gemiddelde Linux Desktop variant is ook tergend traag (dan kijk ik even niet naar de extra functies alla GUI enzo). Programmeurs worden LUI onder Windows, vroeger HAD je maar 640KB ruimte ter beschikking, en was je dus genoodzaakt om je code zo netjes mogelijk te houden. Programma's worden vaak niet goed geoptimaliseerd waardoor ze rete traag worden, ook worden er veel features ingebouwd die nergens goed voor zijn (en niet eens uit te schakelen zijn).

Als ik script in PHP dan probeer ik er voor te zorgen dat de totale runtime van het script zo LAAG mogelijk blijft, dit optimailiseer ik tot de laatste microseconde. Leuk als een gemiddelde pagina 1 seconden kost om te genereren, dan mag je dus maximaal 60 requests per minute hebben, en 3600 per uur. Draait je script door wat optimalisatie op bv 0.05s dan kan je al 1200 request per minut kwijt, en 72000 per uur (hoop dat mn berekening klopt, maargoed, het maakt zeker verschil).

Als ik kan zorgen dat een script van de 0.005 naar 0.004 seconden (gemiddeld) te tunen is dan ben ik al zeer blij, iedere optimailisatie is er weer een extra. Meer vrije CPU tijd, dus weer meer bezoekers/berekeningen die je kan doen.

Doe je dit niet dan krijg je Fok! software (dikke servers, kut software) >:) .

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

KingOfDos: je draait de zaken een beetje om. Natuurlijk is efficentie tegenwoordig stuk minder belangrijk, maar goed ontworpen programma's juist destemeer. Het is echt onzin dat je elke laatste cycle eruit hoeft te kramen, die tijd zijn we gelukkig lang en breed voorbij (en dat zeg ik als een gamedeveloper). Waar het tegenwoordig om draait is dat code goed is opgezet en makkelijk programmeert. De lezer kan beter zien wat er staat en de developer kan later z'n applicatie makkelijker uitbreiden met andere features. En pas daarna ga je aan de slag met optimaliseren waar nodig.

En leuk, dat voorbeeld van de 386, maar je loopt daar even aan het feit voorbij dat de gemiddelde applicatie van toen slechts een fractie van de hoeveelheid code waren van de applicaties van nu. Grote applicaties op de manier van toen ontwerpen is een crime en de development-tijd zal vele malen langer zijn.

En als snelheid écht zo belangrijk is moet je ook geen PHP gebruiken :)

[ Voor 34% gewijzigd door .oisyn op 29-05-2006 23:37 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
bartje321 schreef op maandag 29 mei 2006 @ 19:33:
je kunt natuurlijk ook valsspelen :)

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
char functie(int parameter){
    if(parameter == 1){
        return 'a';
    }else if(parameter == 2){
        return 'b';     
    }else if(parameter == 3){
        return 'c';     
    }
    return 'd';         
}

char prefunctie(int parameter){
    char result = functie(parameter);
    //whie, single exit point
    return result;
}
Zonder aan leesbaarheid of functionaliteit in te boeten kan die onderste functie ook als volgt:
Java:
1
2
3
char prefunctie(int parameter){
    return functie(parameter);
}
En dan valt hopelijk op hoe onzinnig het is.
Als je puur een bepaald coding style principe na wilt leven en dan wel op zo'n manier vals speelt heb je last van cognitieve dissonantie. :Y)
edit:
Anders kijk ik ff over pagina 2 heen :X

[ Voor 43% gewijzigd door Voutloos op 29-05-2006 23:27 ]

{signature}


  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
Hoewel optimaliseren altijd uitdagend is vraag ik me soms af of het wel rendabel is om een app 10x te checken waar het sneller kan. Natuurlijk leer je er wel van, en dat wat je eruit leert neem je in een volgende app gewoonweg mee :)

[ Voor 27% gewijzigd door XWB op 29-05-2006 23:28 ]

March of the Eagles


Verwijderd

.oisyn schreef op maandag 29 mei 2006 @ 23:21:
KingOfDos: je draait de zaken een beetje om. Natuurlijk is efficentie tegenwoordig stuk minder belangrijk, maar goed ontworpen programma's juist destemeer. Het is echt onzin dat je elke laatste cycle eruit hoeft te kramen, die tijd zijn we gelukkig lang en breed voorbij (en dat zeg ik als een gamedeveloper).
Daar heb je zeker gelijk in, het gaat mij er om dat er soms zulke ranzige constructies gebruikt worden waardoor het gewoon trager dan nodig gaat.
En als snelheid écht zo belangrijk is moet je ook geen PHP gebruiken :)
Snelheid is in zoverre belangrijk dat de gebruiker geen 3 seconden hoeft te wachten op een internetpagina. Dat word door de gebruiker als "zeer frustrerend" ervaren, en daardoor word oa een website sneller afgesloten (of tenzij je weet dat er op die trage site zinnige content staat, die je echt nodig hebt). Ik ga ook niet voor de 0.000001 seconden die ik kan optimaliseren, maar als er 0.005 vanaf kan dmv een simpele optimalisatie, dan doe ik dat zeker.

Misschien ligt het aan mij, omdat ik gewoon "willekeurig" begin te ontwikkelen (oké ik schrijf wel iets uit, meer een eisenpakket dan een PSD (of hoe heet zo'n diagram?)). Ik heb wel in veel "basis" functies een timer draaien om te kijken waar veel tijd in gaat zitten (denk aan de volgende counters: db, template, main, userauthenticatie, etc).

"Persoonlijk" geef ik webapplicaties meer toekomst dan lokale. Ik denk dat het "mainframe" idee wel weer terug gaat komen voor bepaalde soort apps, dit oa ivm de stijgende energiekosten (1 dikke server en 100 thin clients/SSF's (linux+browser) gebruiken minder stroom dan 100 desktops met lokale apps), en een beetje hippy gevoel: Goed voor de natuur ;) :9
Maargoed ik wil geen topic-hijack doen over het energieverbruik, dat is lichtelijk offtopic.

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 20-02 15:44
Beperkt de scope even tot mijn (en de meeste) bekende ervaring: PHP voor websites .e.d. De vertraging zit niet in het ene loopje meer, die paar functieaanroepen extra of wat dan ook. Dit zit in het wachten op de database, het resizen van afbeeldingen enzovoorts. Pas bij tig-duizend loops (wat meestal een development fout is uitgezonderd enkele programma's) worden dat soort optimalisaties een puntje.

Wat betreft het "safe & secure": Heel simpel gesteld: In de PHP scripts die ik heb gezien, ook redelijk nette etcetera, is het volgens mij maar beter dat je gewoon stopt als er functie niet meer verder kan. Je weet dan 100% zeker dat er in geval van bugjes: Toch een query uitvoeren met de ongeldige waarde omdat de variablenaam er op lijkt enzovoorts je blij bent dat dit return de code gewoon stopt, iets wat ook logisch is eigenlijk?

Als we het dus over scripts hebben e.d. en dus niet over de high-end applicaties waar teams van tig man aan werken denk ik niet dat je een punt hebt. Dat je op jouw vakgebied gelijk hebt is begrijpelijk maar praktisch gezien niet voor de meesten hier.

Verwijderd

Zomaar eens een vraagje want ik gebruik namelijk een nogal andere coding style als de meesten (als voorbeeld):

PHP:
1
2
3
4
5
6
7
8
9
10
<?php
if($a == true)
{
     echo "Test 1";
}
else
{
     echo "Test 2";
}
?>


In plaats van
PHP:
1
2
3
4
5
6
7
<?php
if($a == true){
     echo "Test 1";
}else{
     echo "Test 2";
}
?>


Omdat ik het eerste voorbeeld veel overzichtelijker vind dan het tweede, maar is dit nu volgens de richtlijnen ook een goede manier of is de tweede manier nu beter volgens de richtlijnen?

[ Voor 29% gewijzigd door Verwijderd op 30-05-2006 08:50 ]


  • 12_0_13
  • Registratie: April 2004
  • Laatst online: 12-02 13:19
Ik vind het de grootste onzin om een boolean te checken tegen true (of false), en snap ook niet dat jullie daaraan meewerken.

Gebruik een fatsonelijke naam voor je variabele, en je kan de code gewoon lezen. Dus niet:

C++:
1
if (a==true) {}


maar

C++:
1
if (isLimited) {}


booleans beginnen met is.... en has.... en lezen vanzelf. Wil je de negatie checken, gebruik dan de not operator. Hiermee voorkom je allerlei fouten als het per ongeluk assignen (= ipv ==) en je code wordt leesbaarder en makkelijker onderhoudbaar.

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 03:57
Verwijderd schreef op dinsdag 30 mei 2006 @ 08:49:
Omdat ik het eerste voorbeeld veel overzichtelijker vind dan het tweede, maar is dit nu volgens de richtlijnen ook een goede manier of is de tweede manier nu beter volgens de richtlijnen?
Wat mij betreft is dit een geval van persoonlijke voorkeur (thuis) of afhankelijk van de afgesproken coding guidelines (op het werk).
12_0_13 schreef op dinsdag 30 mei 2006 @ 09:03:
Ik vind het de grootste onzin om een boolean te checken tegen true (of false), en snap ook niet dat jullie daaraan meewerken.

Gebruik een fatsonelijke naam voor je variabele, en je kan de code gewoon lezen. Dus niet:

C++:
1
if (a==true) {}


maar

C++:
1
if (isLimited) {}


booleans beginnen met is.... en has.... en lezen vanzelf. Wil je de negatie checken, gebruik dan de not operator. Hiermee voorkom je allerlei fouten als het per ongeluk assignen (= ipv ==) en je code wordt leesbaarder en makkelijker onderhoudbaar.
Hulde! Helemaal mee eens!

Roomba E5 te koop


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 20-02 14:32
Als je het mij vraagt doen alle genoemde zaken in dit topic er niet toe wat betreft fout preventie in code. Wat er werkelijk toe doet is dat er in een uniforme stijl geprogrammeerd wordt. Want wanneer sluipen fouten in code, als er meer mensen aan gewerkt hebben.

Tevens is code stijl van ondergeschikt belang aan de kwaliteit van de controles op pre en postcondities van een verwerking. Dus wat je doet als je een functie/method binnenkomt en weer uitgaat.

Persoonlijk geef ik een voorkeur aan een single point of return, behalve voor error/pre conditie controles. Bij een error/preconditie controle geef ik graag op de plek zelf terug dat er een probleem is. En dan maakt het niet uit of ik rapporteer middels een exception of een magic value.

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
public int stukjeOnzin() {
    if(erIsStrontAanDeKnikker()) {
        return -1;
    }

    int result = 0

    ikDoeMijnDing();
    ikOok();
    result = enIkWeetHetResultaat();

    if(maarAlsIkHetVindKrijgenWeIetsAnders()) {
        result = ikMaakErLekkerGehaktVan();
    }

    return result;
}
...


Overigens is het bij single point of return proggen aan te raden om een vaste variabele naam te gebruiken voor je resultaat. Bijvoorbeeld result. Deze variabele kun je dan eventueel opnemen in de highlighting regels van je IDE/Editor. Zodat ie lekker makkelijk te vinden is.

  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 20-02 09:23

LauPro

Prof Mierenneuke®

Verwijderd schreef op dinsdag 30 mei 2006 @ 08:49:
Zomaar eens een vraagje want ik gebruik namelijk een nogal andere coding style als de meesten (als voorbeeld):
Dit is een hele gevaarlijke discussie :o deze is 20 jaar geleden begonnen en daar zijn inmiddels al bijna doden bij gevallen ;) . Persoonlijk ben ik aanhangen van de Kernighan & Ritchie-stijl. Zie o.a.: http://www.cs.usyd.edu.au/~scilect/tpop/handouts/Style.htm. Daarnaast gebruik ik altijd tabs in plaats van spaties! Dit is ook een heel gevoelig punt. De stijl die ik handhaaf:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
namespace foospace {
class Bar {
public:
    int foo();
private:
    int m_foo;
};

int Bar::foo() {
    switch (x) {
    case 1:
        break;
    default:
        break;
    }
    if (isBar) {
        bar();
        return m_foo+1;
    }else{
        return 0;
    }
}
}


Wat er alleen af wijkt van de K&R-methode zijn de extra accolades bij het laatste else-statement. En ik zet de punt ter afsluiting van een klasse-definitie direct achter een accolade ipv op een nieuwe regel.

GNU heeft ook een style waarbij men gebruik maakt twee spaties om in te springen, dit vind ik een beetje kortzichtig. Bij de Linux-style zie ik een inconsequentie waarbij accolades bij namespaces/klassen/functies op een aparte regel moeten maar bij if, switch, etc statements niet.

Bij ANSI komt alles op een nieuwe regel, dat vind ik de code nodeloos lang en complex maken. Hiermee kan je je code veel moeilijker overzien of je moet enorm grote schermen hebben.

[ Voor 22% gewijzigd door LauPro op 30-05-2006 09:48 ]

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
@olger1024
Ook ik verkies de eerste methode, maar dat komt ook omdat ik graag kommentaar voor een block zet:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
/* testen op aanwezigheid van .... */
if($a == true)
/*                                                                                      */
/* Het is aanwezig. De volgende volgorde is belangrijk a, b, c, omdat ... blabla        */
{
     echo "Test 1";
}
else
/*                                                                                      */
/* Het is niet aanwezig, opruimen in de volgende volgorde is belangrijk want ... blabla */
{
     echo "Test 2";
}
?>

Ik kan de reacties al weer voorstellen ... kies dan goede variabelen en niet $a. Dat doe ik zeker, maar bepaalde gedachtenkronkels om een bepaalde sequence te volgen schrijf ik ook op zodat ik na een jaar mijn eigen code ook nog weer kan lezen.

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


Verwijderd

hamsteggot schreef op dinsdag 30 mei 2006 @ 09:47:
@olger1024
Ook ik verkies de eerste methode, maar dat komt ook omdat ik graag kommentaar voor een block zet:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
/* testen op aanwezigheid van .... */
if($a == true)
/*                                                                                      */
/* Het is aanwezig. De volgende volgorde is belangrijk a, b, c, omdat ... blabla        */
{
     echo "Test 1";
}
else
/*                                                                                      */
/* Het is niet aanwezig, opruimen in de volgende volgorde is belangrijk want ... blabla */
{
     echo "Test 2";
}
?>

Ik kan de reacties al weer voorstellen ... kies dan goede variabelen en niet $a. Dat doe ik zeker, maar bepaalde gedachtenkronkels om een bepaalde sequence te volgen schrijf ik ook op zodat ik na een jaar mijn eigen code ook nog weer kan lezen.
Daar ben ik dus ook mee eens maar ik wees alleen $a maar even aan als voorbeeld :) ik zal er de volgende keer $voorbeeld van maken :P

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik weet het, het is een nutteloze discussie, maar
LauPro schreef op dinsdag 30 mei 2006 @ 09:45:
Bij ANSI komt alles op een nieuwe regel, dat vind ik de code nodeloos lang en complex maken. Hiermee kan je je code veel moeilijker overzien of je moet enorm grote schermen hebben.
Correctie, hiermee kan jij je code moeilijker overzien. Ik vind het juist prettiger leesbaar, vooral als de conditie in een if bijvoorbeeld meerdere regels beslaat.
C++:
1
2
3
4
5
6
if ((conditie1 && conditie2) ||
    (conditie3 && conditie4) ||
    (conditie5 && conditie6))
{
    // .. code
}


Ook is het handig omdat je dan de if kunt uitcommenten zonder dat je code breekt (handig tijdens het debuggen), en de condities en de compounds apart van elkaar kunt copypasten. Om nog maar niet te spreken over conditional code in C/C++, waar je met portable code al snel mee te maken hebt:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
#if BUILD_WINDOWS
if (Renderer::NextGenRendering())
#endif
{
    // doe next-gen stuff voor pc, xbox360, ps3
}
#if BUILD_WINDOWS
else
{
    // doe prev-gen stuff voor pc
}
#endif


En grote schermen zijn sowieso een pre bij development, ik heb hier op m'n werk een 22" @ 1920x1440 en een 19" @ 1600x1200, en ik vind het :9

[ Voor 26% gewijzigd door .oisyn op 30-05-2006 11:20 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 20-02 09:23

LauPro

Prof Mierenneuke®

.oisyn schreef op dinsdag 30 mei 2006 @ 11:14:
Correctie, hiermee kan jij je code moeilijker overzien. Ik vind het juist prettiger leesbaar, vooral als de conditie in een if bijvoorbeeld meerdere regels beslaat.
Het is geen gevoel, het is een gegeven. Feitenlijk is het zo dat wanneer je meer linebreaks in je code stopt dat de code moeilijker te overzien wordt, ergo er passen namelijk minder regels op je scherm (bij hetzelfde lettertype/resolutie). Dus per saldo zal je een kleine scope van je code op het scherm kunnen vertonen. Dat het hierdoor wellicht leesbaarder wordt is een heel ander verhaal.
Ook is het handig omdat je dan de if kunt uitcommenten zonder dat je code breekt (handig tijdens het debuggen), en de condities en de compounds apart van elkaar kunt copypasten. Om nog maar niet te spreken over conditional code in C/C++, waar je met portable code al snel mee te maken hebt:
Hoe bedoel je dit? Wanneer je alleen regel met if uitcomment met // dan krijg je in dat geval gewoon dikke parse error. Dan moet je dus werken met /* */. Of bedoel je het individueel uitcommenten van parameters/vergelijkingen? Dit lijkt me een zeer gevaarlijke activiteit. Voordat je het weet geeft je hierdoor parameters verkeerde waardes mee of verbouw je je statement er zo mee dat er een lek ontstaat. Sowieso moet je naar mijn idee niet inline gaan commenten (dus in de conditieclausule bij een if, for etc.).

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

The nice thing about standards is that there are so many to choose from.
;)

Puur ter illustratie: het single return-principe en het guard clause-principe. Beiden door guru's verdedigd, beiden hebben hun nadelen. Verzamel je eigen argumenten, belicht alleen de zwakheden van de andere optie .. tada!

Het denken in absoluutheden vind ik zeer achterhaald. Ik geloof daar niet zo in. Het mooiste van Applying UML and Patterns vind ik dat er nergens wordt gesproken over good/bad, maar over better/worse. Het zijn namelijk vrijwel altijd afwegingen die je maakt.

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 00:09

Janoz

Moderator Devschuur®

!litemod

Een groter scherm is voor mij nog geen reden om mijn code ook maar breder te maken. Ik probeer zoveel mogelijk max 80 aan te houden. Wanneer het te breed wordt lees het lastig. Wanneer je aan het einde van een regel bent is het begin van de volgende regel soms lastig te vinden omdat het relatief ver weg is.

@hamsteggot
Ik heb het idee dat veel van je stellingen zijn gebaseerd op C.

--Single point of exit (dus maar 1 return statement)
Ben ik eerder al op in gegaan. Meest valide argument hiertegen vind ik het volgende. Zoals al veel voorgesteld als alternatief wordt er in de hele functie een waarde bijgehouden die aan het eind wordt gereturned. Voor een compiler (of profiler desnoods) zijn de toekennen aan deze variable een stuk lastiger bij te houden. Een vergeten return is makkelijker te detecteren dan een vergeten toekenning.

--Altijd booleans checken tegen hun waarde (a==true)
Dit lijkt me een door het gebruik van C ingegeven eis. In een stronge typed taal waarin wel een native boolean zit heb je het probleem niet.

--Altijd nieuwe context in {} zetten, ook bij 1 statement
Eens

--Nooit meerder statements op 1 regel (for loop is uitzondering, ++=1 statement)
Eens

--Functies nooit aanroepen met berekeningen in de parameter list (drukaf(2*b+1);)
Ook dit lijkt me een door het gerbuik van C ingegeven eis. Dit levert problemen op wanneer je by ref door gaat geven. Wanneer het de duidelijkheid niet aantast zet ik ze toch liever zo erin. Ik hou er niet van om de scope te vervuilen met allemaal variabelen die je maar twee regels gebruikt. Zeker bij C zou dit een enorme waslijst geven aan het begin van je functie.

De enige reden die ik in het voordeel van deze stelling vind spreekt is (debug)logging. Als jje de berekende waarde toekent aan een tijdelijke variabele kun je makkelijke een log("blaat : "+tmp) er tussen zetten.

--else...if constructies die meer als twee keer genest zijn, verbieden.
Dat vind ik persoonlijk aan de gewenste functionaliteit liggen. Sowieso wil ik het niet te ver in laten springen. Meer dan 3 a 4 niveaus diep wil ik niet gaan. Als je echter else if gebruikt (dus zonder een { ) spring je niet verder in. Case gebruik ik eigenlijk alleen als de check een primitive gebruikt, of als er meerdere cases meerdere acties nodig hebben (ie het hier en daar weglaten van een break). De reden waarom ik nog veel else if gebruik ipv case is meer door java ingegeven omdat je daar voor een case enkel primitiven kunt gebruiken.

--(enterance/exit tracing van een functie)
Als log informatie? Ja, dat doe ik ook nog wel, maar ik vind het geen vereiste.


@KingOfDos
Daar heb je zeker gelijk in, het gaat mij er om dat er soms zulke ranzige constructies gebruikt worden waardoor het gewoon trager dan nodig gaat.
Het zijn juist van die micro optimalisaties waar ik in mijn post op doel die voor ranzige constructies zorgt. Ik raad je daarom ook aan om vooral ook de tweede allinea van die post door te nemen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

LauPro schreef op dinsdag 30 mei 2006 @ 11:33:
[...]
Het is geen gevoel, het is een gegeven. Feitenlijk is het zo dat wanneer je meer linebreaks in je code stopt dat de code moeilijker te overzien wordt, ergo er passen namelijk minder regels op je scherm (bij hetzelfde lettertype/resolutie). Dus per saldo zal je een kleine scope van je code op het scherm kunnen vertonen. Dat het hierdoor wellicht leesbaarder wordt is een heel ander verhaal.
Euh, overzichtelijkheid heeft ook een groot deel met leesbaarheid te maken, dus hier spreek je jezelf een beetje tegen. Door alle lege regels uit m'n code weg te halen en alle accolades op dezelfde regel te laten beginnen wordt het echt niet overzichtelijker. Net als een boek niet overzichtelijker wordt als hij zonder alinea's geschreven wordt, terwijl er toch echt minder informatie op een pagina past.
Hoe bedoel je dit? Wanneer je alleen regel met if uitcomment met // dan krijg je in dat geval gewoon dikke parse error.
C++:
1
2
3
4
// if (conditie)
{
    // code
}

Dat werkt niet als de { op dezelfde regel als de if() staat.

Overigens is dit ook wel te bereiken door true || vooraan de conditie toe te voegen als ie altijd uitgevoerd moet worden, of false && als ie nooit uitgevoerd moet worden

[ Voor 8% gewijzigd door .oisyn op 30-05-2006 12:04 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Janoz schreef op dinsdag 30 mei 2006 @ 11:36:
Dit lijkt me een door het gebruik van C ingegeven eis. In een stronge typed taal waarin wel een native boolean zit heb je het probleem niet.
C99 heeft een native _Bool, maar helaas geen values voor true en false ;) (je zal met 0 en 1 moeten werken)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

ik gebruik ook de stijl die .oisyn aangeeft. Ik vind ze ook veel beter te overzien.
Op school worden we verplicht van
C++:
1
2
3
4
5
6
7
8
if (isOnzin) {
  printf("Wat een dikke onzin!");
  return onzinnig_getal;
}
else {
  printf("I.Q. += 10");
  return zinnig_getal;
}

Ik vind dit onoverzichtelijk aangezien ik bij een } altijd verticaal omhoog ga tot de vorige { om
de volledige block te identificeren. Als die weg is, durf ik soms een heel stuk hoger uitkomen.

algemene regel:
als een functie niet op 1 scherm past is ze te lang. Maak deelfuncties die bepaalde
functionaliteit overnemen. Een mens kan maar een bepaalde hoeveelheid informatie tegelijk overzien.

Wat alle andere statements betreft:
common sense.

Als ik een bedrijfskritische app schrijf dan schrijf ik codeer ik enkel de logica. Optimalisaties heb je'n compiler voor. Schrijf je'n performance critical app, dan pas kun je je eens bezig gaan houden met globale optimalisatie.

Verder maak je gewoon dat je functie doet wat ie doet, nix meer nix minder.
Als je dan debugmogelijkheden hebt haal je de foute functie er in de meeste gevallen behoorlijk snel uit.

ASSUME makes an ASS out of U and ME


  • EXX
  • Registratie: Juni 2001
  • Laatst online: 19-02 16:54

EXX

EXtended eXchange

Wat ik hier in deze hele discussie mis is 1 ding: goede documentatie.

Je kan je code nog zo netjes maken, als de code niet goed gedocumenteerd is blijft het een hele klus voor de programmeur die de code moet onderhouden.

Veel commentaar in je code schrijven is geen leuk klusje, maar een absolute must.

For it is the doom of men that they forget...           Huidige en vroegere hardware specs         The Z80 is still alive!


  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

En dan is nog de vraag wat voor commentaar.
C#:
1
i++; // verhoog i
Geen geintje :X

Uitleggen waarom je iets doet is m.i. een goede richtlijn. Dat is ook nog eens onafhankelijk van de implementatie.
Als je uitlegt wat je doet, is of je code onduidelijk, of heeft de lezer gewoon een goed boek nodig.
Als je uitlegt hoe je iets doet, loop je het risico dat de code out of sync raakt met het commentaar.

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • EXX
  • Registratie: Juni 2001
  • Laatst online: 19-02 16:54

EXX

EXtended eXchange

Precies.

Waar we iig niet op moeten bouwen is zgn. 'self-explaining code'. Dat is een illusie.

For it is the doom of men that they forget...           Huidige en vroegere hardware specs         The Z80 is still alive!


  • zeroxcool
  • Registratie: Januari 2001
  • Laatst online: 20-02 14:43
hamsteggot, ik ben eerlijk gezegd wel benieuwd naar wat voor een software jij ontwikkelt. Als ik het zo hoor is het behoorlijk mission-critical, kun je daar misschien iets over kwijt?

zeroxcool.net - curity.eu


  • igmar
  • Registratie: April 2000
  • Laatst online: 31-01 23:50

igmar

ISO20022

bartje321 schreef op maandag 29 mei 2006 @ 17:07:
@hamsteggot: wedden dat je ook tegen goto''s bent :) (en ik geef je groot gelijk)
goto's kunnen spaghetti en dubbele code voorkomen :

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
struct blaat {
     char *x;
     char *y;
};

struct blaat * a(void)
{
   struct blaat *x;

   a = malloc(sizeof(struct blaat));
   if (a == NULL)
      goto errout;
   a->x = malloc(sizeof(char) * 10);
   if (a->x == NULL)
      goto errout;

   a->y = malloc(sizeof(char) * 10);
   if (a->y == NULL)
      goto errout;

   return a;

errout:
   if (a->x)
     free(a->x);
   if (a->y)
     free(a->y);
   if (a)
     free(a);

   return NULL;
}


vs

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
struct blaat {
     char *x;
     char *y;
};

struct blaat * a(void)
{
   struct blaat *x;

   a = malloc(sizeof(struct blaat));
   if (a == NULL) {
      return NULL;
   }

   a->x = malloc(sizeof(char) * 10);
   if (a->x == NULL) {
       free(a);
       return NULL);
   }

   a->y = malloc(sizeof(char) * 10);
   if (a->y == NULL) {
     if (a->x)
         free(a->x);
     free(a);
     return NULL;
   }

   return a;
}


't voorbeeld is wat simpel, maar de strekking is denk ik duidelijk. Ik heb zelf wat macro's in elkaar gezet die bv destruct aanroepen, en meteen de pointer op NULL zetten. Verder gebruik ik vrij veel assert's in de code, ik heb teveel gezien dat om echte problemen wordt heen gecode ipv ze structureel te verhelpen.

[ Voor 24% gewijzigd door igmar op 30-05-2006 12:22 ]


  • D4Skunk
  • Registratie: Juni 2003
  • Laatst online: 20-10-2025

D4Skunk

Kind of Blue

Een korte opmerking rond single point of return : wat doe je dan met yield statements ? moet je daarbij dan ook weer zo'n if/else constructie gaan opzetten ? Het lijkt me dat je dan net aan het gemak van yields voorbijgaat ?

Een concept dat ik iets interssanter vind, is dat rond de try/catch en errorhandlers : gebruiken jullie overal dezelfde errorhandlers?
Gebruiken jullie de standaard exceptions of gaan jullie zelf de exceptions gaan definiëren. Mag je exceptions uberhaupt gebruiken om je flow te bepalen, of moet dit echt een geval van uitzondering zijn ? (o.a. om performance-redenen)
Worden de standaard exceptions afgehandeld door steeds dezelfde exception handler of niet ? Is er een apart behandeling voor niet-standaard exceptions...

Quick & Dirty :
C#:
1
2
3
public string StringFromFile(string fn) {
  return File.OpenText(fn).ReadToEnd();
}


Iets uitgebreider (zonder exceptions):
C#:
1
2
3
4
5
6
public string StringFromFile(string fn) {
  // check filename, if not exists log error and return null
  // open file , if failed log error and return null
  // lees file etc...
  return s;
}
igmar schreef op dinsdag 30 mei 2006 @ 12:21:
[...]


goto's kunnen spaghetti en dubbele code voorkomen :

't voorbeeld is wat simpel, maar de strekking is denk ik duidelijk. Ik heb zelf wat macro's in elkaar gezet die bv destruct aanroepen, en meteen de pointer op NULL zetten. Verder gebruik ik vrij veel assert's in de code, ik heb teveel gezien dat om echte problemen wordt heen gecode ipv ze structureel te verhelpen.
Mijn oplossing zou zijn :
C:
1
2
3
4
5
6
7
8
void blaat_destruct(blaat *a) {
   if (a->x)
     free(a->x);
   if (a->y)
     free(a->y);
   if (a)
     free(a);
}


Want waarschijnlijk moet je die destructor nog wel meer aanroepen ? Goto's zouden echt wel enkel in extreme gevallen mogen gebruikt worden, en dan nog...

offtopic:
in je voorbeeld bedoel je trouwens waarschijnlijk :
[code]
struct blaat * a(void)
{
struct blaat *a; //a ipv x, anders kloppen je assignments niet meer

a = malloc(sizeof(struct blaat));
if (a == NULL) {
...
[/code]

[ Voor 35% gewijzigd door D4Skunk op 30-05-2006 12:35 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op maandag 29 mei 2006 @ 22:59:
• Single point of exit (dus maar 1 return statement)
Dit doe ik wel vaak, bij sommige functies gebruik ik er meerdere, maar probeer het te voorkomen. Ik maak altijd netjes een $ret aan, waar mijn return waarde in zit.
Ik escape uit een functie zo snel ik er niets meer te zoeken heb (anders krijg je van die onnodig geneste structuren). Verder horen functies niet complex te zijn (in de meeste gevallen) dus je moet de flow met beide aanpakken nog steeds goed kunnen zien.
• Altijd booleans checken tegen hun waarde (a==true)
Het heeft geen toegevoegde waarde: alleen maar meer code om te lezen. Je moet een goeie naam bedenken voor je conditie en dan ben je die == true niet nodig. Als ik complexe expressies heb, dan breek ik de expressie wel op in een aantal kleine subexpressies en geef ik daar een naam aan en plaats die in de conditie. Dan kan je tenminste zien wat je aan het doen bent.
• Altijd nieuwe context in {} zetten, ook bij 1 statement
Sinds we code beautifiers hebben heeft volgens mij nog nooit iemand een fout gemaakt zoals de volgende:

code:
1
2
3
if(a > 20 )
     System.out.println("foo");
     System.out.println("bar");


Dus waarom beschermen tegen iets dat fout gaat. En verder pas ik me hierin gewoon netjes bij de bedrijfsstijl aan, dus als het daar moet dan heb ik er niet veel problemen mee. In mijn eigen code doe ik het niet.
• Nooit meerder statements op 1 regel (for loop is uitzondering, ++=1 statement)
True..
• Functies nooit aanroepen met berekeningen in de parameter list (drukaf(2*b+1);)
Geen problemen mee mits de berekening niet te complex is. Als de berekening complex is dan maak ik liever een aantal variabelen aan en bereken daarin de waarden en plaats die erin. Dan kun je in een ook opslag zien wat de bedoeling is.
• else...if constructies die meer als twee keer genest zijn, verbieden.
In principe geen problemen mee. Maar als ik 3 of meer nestings zien dan vind ik dat meestal een beetje fishy en breek het op tot losse methodes waarin meteen duidelijk is wat de bedoeling is.


[edit]
Ik denk dat 'veilig' werken op een hoger nivo hier totaal genegeerd wordt. Er zijn veel belangrijkere issues dan dit soort details: oa structuur binnen een applicatie. Dat zijn de dingen waar echt op gehamerd moet worden. Je moet je dus niet blind staren op dit soort low level details.

[ Voor 7% gewijzigd door Alarmnummer op 30-05-2006 13:00 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

igmar schreef op dinsdag 30 mei 2006 @ 12:21:
[...]


goto's kunnen spaghetti en dubbele code voorkomen :

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
struct blaat {
     char *x;
     char *y;
};

struct blaat * a(void)
{
   struct blaat *x;

   a = malloc(sizeof(struct blaat));
   if (a == NULL)
      goto errout;
   a->x = malloc(sizeof(char) * 10);
   if (a->x == NULL)
      goto errout;

   a->y = malloc(sizeof(char) * 10);
   if (a->y == NULL)
      goto errout;

   return a;

errout:
   if (a->x)
     free(a->x);
   if (a->y)
     free(a->y);
   if (a)
     free(a);

   return NULL;
}
Tja...
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
struct blaat
{
    char * x, * y;
};

blaat * a()
{
    try
    {
        std::auto_ptr<blaat> b (new blaat);
        auto_array<char> x(10), y(10);
        b->x = x.release();
        b->y = y.release();
        return b.release();
    }
    catch(...)
    {
        return 0;
    }
}

// of beter:

struct blaat
{
    blaat() : x(10), y(10)
    {
    }

    std::vector<char> x, y;
};

blaat * a()
{
    return new blaat();
}

Wat mijn eerdere punt weer bewijst :)

[ Voor 6% gewijzigd door .oisyn op 30-05-2006 12:41 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
@LauPro
Het is geen gevoel, het is een gegeven.
Dat is dan jouw gegeven want ik ben het compleet met je oneens (en een antal guru's ook, Les Hatton voorop). De code zoals geschreven door .oisyn verdient mijn absolute voorkeur. Als je een regel code moet verdelen over meerdere regels (>5) moet je jezelf so-wie-zo de vraag stellen of dat wat je schrijft wel goed is.

Wat wel een gegeven is, is dat 80 characters eigenlijk al te breed is voor het menselijke brein. Kranten maken heel bewust gebruik van colommen omdat de lezer anders niet in staat is zijn aandacht vast te houden. Onderzoeken op web-pagina's geven heel duidelijk aan dat gemiddeld genomen rechts boven het meest gelezen stukje is ('F' patroon), je hebt het dan over 3,4 regels met maximaal 40 characters.

Dat jij in staat bent lange regels te lezen komt omdat je de regels zelf hebt geschreven en de context erachter snapt. Een ander zal niet zo gemakkelijk jouw lange regels snappen. Vaak is het uitgangspunt van code schrijven om het zo te schrijven dat anderen het ook kunnen lezen (en als je je eigen code na een jaar terug ziet voel je je ook een vreemde).

Voor het antwoord op je tweede vraag zou ik maar eens gaan kijken bij het hoofdstuk pre-compiler directives. Als je multi platform ontwikkeld zijn dit noodzakelijke constructies, mooi of niet.

@Janoz
veel gebaseerd op C
Heb ik nooit ontkent, 90% van de low level embedded wereld is C of een afgeleide daarvan. Het begint wel langzaam te verschuiven. Gelukkig ben ik ook op de hoogte van C++ (iets stricter als C, maar OO deel vind ik niet goed), Java (mooie abstractie concepten, een aantal heb ik in C omgezet) en PHP (helaas geen compiler, heft veel beperkingen van C op en OO is op de goede weg). Expliciete boolean checking is inderdaad hoofdzakelijk een C beperkiing, later programmeertalen hebben hier een strong type voor gefinieerd (C++ volgens mij ook niet, kunt vergelijken met integer).


Weet je, het gaat er niet om welke keuzes je maakt, Kenneth, zei ook al wat van die strekking. Het gaat er wel om dat je afgewogen keuzes maakt die het mogelijk maken om bepaalde fouten, die veel voorkomen voor de gekozen taal, te voorkomen. Een (true==false) constructie verdient geen schoonheidsprijs maar voorkomt wel een aantal veel voorkomende fouten. Evenzo is een bumper op een auto is een noodzakelij kwaad, er zijn genoeg auto's waar het weglaten van die bumper tot een veel kleinere en efficientere auto zou leiden (whow, hoe klein worden die Ka-tjes dan ?).

Te veel mensen reageren vanuit het gevoel of onzin-die-fout-maak-ik-niet. Het niet erkennen van de beperkingen van een programmeertaal of van jezelf als programmeur is het grootste probleem van de programmeerwereld in het algemeen. Het is niet voor niets dat in de afgelopen 20 jaar het aantal fouten per 1000 regels code nog steeds rond de 6 ligt. Ergens zijn wij zelfs slechter geworden want veel van die code wordt door SDE met standaard templates en standaad code generatie, automatisch uitvullen ook nog eens voor ons gemaakt. Waar andere vakgebieden leren van fouten, zijn wij vrij hardnekkig. Een nieuwe taal wordt altijd als een hype ontvangen om later met dezelfde soort problemen naast de andere talen te worden gezet. Ons eigen gedrag zetten we niet onder de loep.

Ik had gehoopt dat vanuit de studies/bedrijven wat meer aandacht besteed werd aan de beperking van talen en programmeurs... maar ben teleurgesteld. Is er niets positiefs te melden? Ja, de mods vallen positief op, hebben kennis van zaken (ondanks dat ze het op punten oneens zijn met mij, maar daarvoor is dit forum :D ).

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Wheehehe, C++ OO vind je niet goed maar PHP OO is op de goede weg? :D
Iets zegt me dat je toch niet zo heel erg op de hoogte bent van C++. Zie m'n code hierboven, het is niet alleen een toegevoegde OO, het is een heel ander (en veilig) paradigima waar je in programmeert (kunt programmeren eigenlijk).

[ Voor 67% gewijzigd door .oisyn op 30-05-2006 12:51 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

kenneth schreef op dinsdag 30 mei 2006 @ 12:06:
En dan is nog de vraag wat voor commentaar.
C#:
1
i++; // verhoog i
Geen geintje :X

Uitleggen waarom je iets doet is m.i. een goede richtlijn. Dat is ook nog eens onafhankelijk van de implementatie.
Niet helemaal mee eens. Het moet redelijk logisch blijken 'waarom' je dingen doet. Anders krijg je dit soort nutteloosheden:
C++:
1
2
3
4
5
f::~f()
{
  // Close file handle because else we leak resources
  if (m_hFile != INVALID_HANDLE_VALUE) ::CloseHandle(m_hFile);
}

Lijkt me redelijk obvious waarom je files sluit in een destructor van een class. Wel verdient het een commentaar als je bepaalde dingen doet die niet logisch zijn, zoals bijvoorbeeld het open laten van de file. Vaak voorzie ik zo'n situatie ook nog van een commentaar waar die file dan nog verder gebruikt wordt en waar het closen wel plaats vindt, zodat iemand anders dat ook weer terug kan vinden.
Als je uitlegt wat je doet, is of je code onduidelijk, of heeft de lezer gewoon een goed boek nodig.
Ook niet helemaal mee eens. Je moet er van uit kunnen gaan dat de persoon die je code leest de taal machtig is, dus dat hoef je niet uit te leggen. Maar als commentaar in een functie even uitleggen wat je aan het doen bent kan geen kwaad.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int f::longandcomplex()
{
  // Gather resources
  .
  .
  .

  // Process data we loaded, sort it and remove duplicates. Then update
  // indexes in the second array
  .
  .
  .

  // Calculate the result
  .
  . 
  .
  return nRes;
}

Natuurlijk moet je niet uitleggen wat je individuele instructies doen. In het voorbeeld wat je geeft is inderdaad het commentaar onzinnig, maar zoals hierboven vertellen wat stukken functie doen is imo absoluut zinnig.
Als je uitlegt hoe je iets doet, loop je het risico dat de code out of sync raakt met het commentaar.
Dat ligt er een beetje aan. Ik heb ooit een stukje code geschreven wat uit een bos met triangles (miljoenen) een setje meshes maakt met ongeveer 1000 driehoeken per mesh. Daar voor moet er redelijk wat gezocht worden in de grote buffer, en het eindresultaat moet weer geoptimaliseerd worden naar een set met vertices en een index buffertje. Het heeft dan wel zin om niet alleen per functie te beschrijven wat hij doet, maar om ook de uitleg in grote lijnen ergens in de code op te nemen...
hamsteggot schreef op maandag 29 mei 2006 @ 10:49:
• Single point of exit (dus maar 1 return statement)
Niet mee eens... maar ik hanteer zelf de strategie zoals eerder ook al genoemd in dit topic:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bool f::f(int a, int b, int c)
{
  // Do we have to calculate?
  if (a < b && c > a) return false;

  bool bRes = false;
  . 
  .
  .
  // calculate
  .
  .
  .
  return bRes;
}

Dus exit points aan het begin en aan het eind, maar over het algemeen niet ergens in het midden.
• Altijd booleans checken tegen hun waarde (a==true)
Nee. Het logisch naamgeven van booleans maakt dit overbodig imo.
• Altijd nieuwe context in {} zetten, ook bij 1 statement
Ook mee oneens. Behalve als het de leesbaarheid van een stuk code heel erg bevordert (met een aantal geneste ifs bijv).
• Nooit meerder statements op 1 regel (for loop is uitzondering, ++=1 statement)
Ook oneens.
C++:
1
2
3
4
5
6
7
8
  // Liever dit...
  while (m_pListHead) DeleteNode();

  // Dan
  while (m_pListHead != NULL)
  {
    DeleteFirstNode();
  }
• Functies nooit aanroepen met berekeningen in de parameter list (drukaf(2*b+1);)
Ook niet mee eens. Tenzij het enorme lijsten met berekeningen zijn of dingen met bij-effecten. Jouw voorbeeld vind ik dus prima, maar iets als:
C++:
1
2
  v = Functie(i++, ++j, DeleteHeadNode() 
         ? CreateList() : SomethingElse());

Dat weer liever niet :)
• else...if constructies die meer als twee keer genest zijn, verbieden.
Enigszins mee eens. Het is vaak beter nog eens naar dat soort code te kijken, aangezien het meestal veel simpeler en leesbaarder op te schrijven is.

  • igmar
  • Registratie: April 2000
  • Laatst online: 31-01 23:50

igmar

ISO20022

.oisyn schreef op dinsdag 30 mei 2006 @ 12:39:
[...]

Tja...
<snip c++ code>
Wat mijn eerdere punt weer bewijst :)
Mijn C++ is zo roestig als de Titanic, maar het idee is hetzelfde zover ik kan zien :) Ik vind reperterende code voor error-afhandeling gewoonweg vreselijk, en als je vervolgens dingen in de struct aanpast moet je alle condities weer af. Dit is wat mij betreft ook meteen de enige correcte toepassing van een goto.

  • igmar
  • Registratie: April 2000
  • Laatst online: 31-01 23:50

igmar

ISO20022

hamsteggot schreef op maandag 29 mei 2006 @ 10:49:
• Functies nooit aanroepen met berekeningen in de parameter list (drukaf(2*b+1);)
Dit heeft er meer mee te maken dat in C je geen waarde van een object meer dan 1 keer mag veranderen zonder sequence point :

C:
1
a[i] = i++;


geeft dus undefined behaviour. Een ander issue waarom dat wel eens wordt gezegd is dat als er macro's worden gebruikt die het gedrag van een een programma kunnen veranderen afhankelijk van defines. Verder hou ik als regel aan : als het leesbaar is is het acceptabel.

  • igmar
  • Registratie: April 2000
  • Laatst online: 31-01 23:50

igmar

ISO20022

hamsteggot schreef op maandag 29 mei 2006 @ 20:59:
in c voorkomt dit grove fouten. Een goede compiler geeft different types als dit bij een assignment of conditie wordt gebruikt. Nog mooier is het om de constante voor de variabele te zetten; true == a. Als er een '=' vergeten wordt zal de compiler klagen over constant can not be assigned a value.
Een kwestie van warnings aanzetten, en het liefs elke warning een error laten zijn. Ik compile standaard alle mijn code op die manier.
Na 15 jaar professioneel programmeren ben ik ook hier niet meer mee eens. In den beginne riep ik dit ook test suites kunnen alles ... dacht ik. Maar als je ziet in de statistieken waar de grootste hoeveelheid niet functionele fouten direct te vinden is, is dat in de stijl van programmeren. Bij duizenden regels code, kun je niet alles meer testen. Code reviews worden voor mij een steeds zwaarder punt om de echte winst te pakken op niet functionele fouten en een duidelijke stijl is dan nodig om met elkaar 1 soort code op te leveren.
Gedeeltelijk. Functies moeten simpel zijn en een ding doen. Als je iets doet op een socket, en die moet connected zijn, check daar dan ook, en assert() of abort() als dat niet het geval is. Vervolgens in dezelfde functie een connectie opbouwen is echt not-done wat mij betreft.

Mijn code staat vol met assert()'s, en verder is valgrind echt een uitkomst : Het spaart echt uren zoekwerk naar obscure bugs.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

igmar schreef op dinsdag 30 mei 2006 @ 13:29:

Mijn C++ is zo roestig als de Titanic, maar het idee is hetzelfde zover ik kan zien :) Ik vind reperterende code voor error-afhandeling gewoonweg vreselijk, en als je vervolgens dingen in de struct aanpast moet je alle condities weer af. Dit is wat mij betreft ook meteen de enige correcte toepassing van een goto.
Mijn punt was juist dat je die goto's niet nodig hebt in modernere talen met destructors of iets aanverwants :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
.oisyn schreef op dinsdag 30 mei 2006 @ 12:47:
Wheehehe, C++ OO vind je niet goed maar PHP OO is op de goede weg? :D
Iets zegt me dat je toch niet zo heel erg op de hoogte bent van C++. Zie m'n code hierboven, het is niet alleen een toegevoegde OO, het is een heel ander (en veilig) paradigima waar je in programmeert (kunt programmeren eigenlijk).
Je geeft je eigen antwoord al: ...kunt... met C++ kun je op eenzelfde gestructureerde manier programmeren als Java en daar zit een enorme kracht, de structuren zijn echter zo loose dat je er net zo makkelijk kunt mixen met native (> kans op fouten). Het statement: de beste subset van C++ is C is provocerend maar bevat een kern van waarheid. Op dat punt hinkt PHP op dit moment ook nog (en is dus nu niet beter als C++, vanuit functionaliteit bekeken) maar de discussies die gevoerd worden bij de doorontwikkeling van deze taal gaan de goede kant op (vind ik, mag ik me ook eens positief opstellen ;) ).

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 17-02 18:22
Ik heb geen idee waarom je denkt dat PHP een taal is die ook maar enigszins geschikt is voor bedrijfscritische toepassingen. Als je Java loose vindt, het C++ al te veel 'makkelijke features' vindt hebben, denk ik dat je PHP totaal niet kent.

Je hebt een goede programmeer nodig om ervoor te zorgen dat je code duidelijk en leesbaar in elkaar zit. Ook is de OO nog lang niet waar ik het graag heen zou zien gaan. En dan hebben we het nog niet over loose typing.

[ Voor 13% gewijzigd door Mithrandir op 30-05-2006 14:12 ]

Verbouwing


  • igmar
  • Registratie: April 2000
  • Laatst online: 31-01 23:50

igmar

ISO20022

.oisyn schreef op dinsdag 30 mei 2006 @ 13:50:
Mijn punt was juist dat je die goto's niet nodig hebt in modernere talen met destructors of iets aanverwants :)
Inderdaad. In niet zulke moderne talen is mijn constructie denk ik het beste alternatief :) In C++ heb ik het eigenlijk ook altijd op een soortgelijke manier als jouw voorbeeld gedaan.

  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
Mithrandir schreef op dinsdag 30 mei 2006 @ 14:11:
Ik heb geen idee waarom je denkt dat PHP een taal is die ook maar enigszins geschikt is voor bedrijfscritische toepassingen. Als je Java loose vindt, het C++ al te veel 'makkelijke features' vindt hebben, denk ik dat je PHP totaal niet kent.

Je hebt een goede programmeer nodig om ervoor te zorgen dat je code duidelijk en leesbaar in elkaar zit. Ook is de OO nog lang niet waar ik het graag heen zou zien gaan. En dan hebben we het nog niet over loose typing.
Dat zijn een berg aannames zeg.
1. Java is niet loose, een van de zuiverste talen die ik ken (op een paar logische programmeertalen na). Herlees de zin even want zo als jij het schrijft staat het er niet. Java is echter te traag voor critische toepassingen en interfacing met hardware is moeilijk.
2. Tja, mijn kennis over PHP ... ik zal nooit beweren dat ik een taal ken maar geloof wel dat ik mijn weg weet in PHP. Het gemak waarmee bij PHP native en objecten door elkaar kunnen lopen (zie ook C++) is zeker geen plus maar er zijn stromingen die daar aan werken ... dat ze het probleem onderkennen vind ik een grote plus. Wat er uitkomt dat weet ik ook niet en kan wel de grootste bagger in jaren zijn.
3. PHP voor bedrijfscritische toepassingen ... heb ik nergens beweerd ... en hangt er vanaf. Ik werk op dit moment aan een totaal oplossingen voor web-based projectmanagement in een project team en geloof er wel in. Een heel critisch proces met veel database interacties en pittige berekeningen; Basis is PHP, en ook JS en Java lopen vrolijk door elkaar. Wat is critisch? Voor het maken van programma's voor hardware kan PHP niet wat er bestaat geen PHP (cross)compiler. PHP voor embedded toepassingen... dat zou leuk zijn :Y) .

Het is mijn ervaring dat een programmeertaal geschikt is voor een bepaald toepassingsgebied. De talen onderling bekijkend zijn ze geen van allen perfect ... ik heb ook geen voorkeur voor een taal. Je moet kijken naar je doel en daar de juiste taal bij pakken.

Critisch zijn over een taal vind ik wel heel belangrijk, voor- maar ook nadelen kennen. Goede coding conventions hebben voorkomen bepaalde programmeer fouten en daar gaat dit topic over.

[ Voor 3% gewijzigd door hamsteg op 30-05-2006 14:46 ]

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 20-02 23:20
hamsteggot schreef op dinsdag 30 mei 2006 @ 14:44:
[...]
Java is echter te traag voor critische toepassingen
Dan ben ik benieuwd naar jouw definitie van kritische toepassingen, want voor de ontwikkeling van enterprise software is Java toch een van de populairste platformen.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 00:09

Janoz

Moderator Devschuur®

!litemod

Ik denk dat hamsteggot met kritisch hier meer embedded en realtime applicaties bedoeldt.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 17-02 18:22
hamsteggot:

Okee, daar heb je wel een aantal punten waarin ik je gelijk moet geven. Sommige aannames van mij waren inderdaad een beetje uit de lucht gegrepen.

Bij punt 1 heb ik je dan inderdaad verkeerd begrepen over Java.
2: De mensen die achter PHP zitten vind ik niet bepaald de goede weg in gaan. Sommige dingen pakken ze wel redelijk goed aan, zoals het verbeteren van het belachelijke OO-design van PHP4, maar in mijn ogen blijven ze teveel backwards compatible (maar niet helemaal, dus je code breekt met nieuwe versies toch nog).
3: Als je een goed team hebt kun je wel op PHP vertrouwen, dat geloof ik zeker. Een van de grootste problemen van PHP is natuurlijk de enorme userbase met prutsers, waardoor er enorm veel code te vinden is die totaal niet safe of secure is. En dat haalt de taal als geheel toch ook naar beneden.

Over iets heel anders:
Ik snap nog steeds niet waarom je het volgende checkt:
code:
1
2
if(true == isValid) { //doe iets
}


In plaats van gewoon
code:
1
2
if(isValid) { // doe iets
}


Wat is het voordeel? Leesbaarder wordt het er niet van, minder gevaarlijk? Ik weet geen voorbeeld waarbij het beter werkt dan als je het vergelijkt met true.
Nu zal dit misschien per taal verschillen, maar ik zou graag een voorbeeld zien :)

Verbouwing


  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Och, zolang de PHP-devs aan het overwegen zijn om namespaces in te voeren, blijft PHP m.i. gewoon een Q&D-platform. Dat, en andere redenen.

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 00:09

Janoz

Moderator Devschuur®

!litemod

Enige echte voordeel is dat je een foutmelding krijgt wanneer je een enkele = gebruikt ipv een ==. Bij een enkele = probeer je iets aan een constante toe te kennen en dat wil niet.

Ikzelf gebruik het niet zo. Een andere variant hierop echter wel:

code:
1
2
3
if ("constantewaarde".equals(var)){ 
  //code
}

Door juist de equal methode van de constante aan te roepen is gegarandeerd dat deze niet null is en dus geen nullpointer op kan gooien.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
Volledig uitgewerkt voor Mithrandir:
C kent geen type boolean. Vaak is het een typedef / enum (=integer).
C:
1
2
3
4
if (true == isValid) 
{ 
  //doe iets 
}

De controle is expliciet nodig omdat in een integer range meer getallen vallen dan 0 en 1. Bij getallen geldt verder dat if( 0 ) --> foute conditie, if( elk-ander-getal ) --> goede conditie. Toch geven functies vaak precies het omgekeerde terug 0 = geen fout en elk ander getal geeft een error code terug. Dit wordt vaak door elkaar gehaald. Je moet gewoon testen op je enum types (nadeel van C).

Voor de C taal is het volgende allemaal goed
if ( var )
if ( var=int )
if ( var==int )
if ( !var )
if ( !int)
if ( var=!int )
Met name de tweede en de zesde regel zijn vaak type-fouten (een assignment in een if is echt dirty programmeren). door een integer voorop te zetten:
if ( int = var )
if ( int = !var )
Zal de compiler klagen over: (const) int value can not be assigned a value. Een truukje om type fouten te voorkomen.

[ Voor 8% gewijzigd door hamsteg op 30-05-2006 16:35 ]

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 20-02 09:23

LauPro

Prof Mierenneuke®

.oisyn schreef op dinsdag 30 mei 2006 @ 11:49:
Euh, overzichtelijkheid heeft ook een groot deel met leesbaarheid te maken, dus hier spreek je jezelf een beetje tegen. Door alle lege regels uit m'n code weg te halen en alle accolades op dezelfde regel te laten beginnen wordt het echt niet overzichtelijker. Net als een boek niet overzichtelijker wordt als hij zonder alinea's geschreven wordt, terwijl er toch echt minder informatie op een pagina past.
Laat ik het zo uitleggen: ik ben vang mening dat je uiteraard indien mogelijk je regels zo kort mogelijk moet houden, maar er moet geen absoluut zijn (zoals bijv. 80 karakters op 1 regel). En beetje editor line-wrapt alle regels die te lang zijn voor je viewport. In mijn geval stel ik bijvoorbeeld in dat wanneer een regel langer is dan 80% van de viewport, dat deze gewrapped wordt (en dit is ook duidelijk visueel aangegeven). (Ook @hamsteggot overigens.)
C++:
1
2
3
4
// if (conditie)
{
    // code
}

Dat werkt niet als de { op dezelfde regel als de if() staat.
Klopt, maar waarom zou je dit willen? Ik zie hier aantal hele grote gevaren. Door juist die accolades op dezelfde regel te plaatsen voorkom je dat blokken worden uitgevoerd welke niet uitgevoerd zouden moeten mogen.
Overigens is dit ook wel te bereiken door true || vooraan de conditie toe te voegen als ie altijd uitgevoerd moet worden, of false && als ie nooit uitgevoerd moet worden
Dit is in mijn ogen al een wat elegantere methode, al hoewel het het beste is om gewoon even het hele blok te commenten imo.

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

hamsteggot: Fijn dat je nu wat punten herhaalt die al 34x eerder in de topic zijn genoemd ;)
LauPro schreef op dinsdag 30 mei 2006 @ 16:32:
Klopt, maar waarom zou je dit willen? Ik zie hier aantal hele grote gevaren. Door juist die accolades op dezelfde regel te plaatsen voorkom je dat blokken worden uitgevoerd welke niet uitgevoerd zouden moeten mogen.
Tja, dan kan ik alleen maar vermoeden dat je nooit echt heel erg veel met debugging bezig bent geweest. Soms wil je namelijk juist even dat code altijd wordt uitgevoerd. Accolades op de volgende regel faciliteren dat mooi. Eveneens voor de andere punten die in aandroeg, namelijk het rondkopiëren van blokken code (komt bij refactoring nogal eens voor is mijn ervaring). Maar goed, ieder z'n meug, uiteindelijk is het niets meer dan personal preference :)

[ Voor 101% gewijzigd door .oisyn op 30-05-2006 16:36 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • igmar
  • Registratie: April 2000
  • Laatst online: 31-01 23:50

igmar

ISO20022

hamsteggot schreef op dinsdag 30 mei 2006 @ 16:25:
Zal de compiler klagen over: (const) int value can not be assigned a value. Een truukje om type fouten te voorkomen.
Totaal een non-argument als je het mij vraagt : een assignment levert altijd true op, en een beetje compiler geeft daar gewoon een warning op in combinatie met een if(). Verder is een enum gebruikt als boolean een cosmetisch iets : true is alles ongelijk aan 0.

  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
ZeRoXcOoL schreef op dinsdag 30 mei 2006 @ 12:14:
hamsteggot, ik ben eerlijk gezegd wel benieuwd naar wat voor een software jij ontwikkelt. Als ik het zo hoor is het behoorlijk mission-critical, kun je daar misschien iets over kwijt?
Het is apparatuur die je niet zomaar even open kunt halen om een stukje hardware weer in de regeling te leggen. Rontgen zou een voorbeeld kunnen zijn, dat is meer human-critical :)

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

igmar schreef op dinsdag 30 mei 2006 @ 16:38:
een assignment levert altijd true op
Nee hoor, een assignment levert de geassignde variabele op. Als je dus 0/false/NULL aan iets assignt zal dat dus ook het resultaat zijn van de conditie.
C:
1
2
3
4
if (a = 0)
{
   // deze code wordt nooit uitgevoerd
}


Overigens vind ik het niet zo heel vreemd om een assignment én een check in een if te zetten
C++:
1
2
3
4
5
6
7
void foo(Base * b)
{
    if (Derived * d = dynamic_cast<Derived*>(b))
    {
        // Het is een Derived, doe er iets mee
    }
}

Handig voor een operator==() implementatie. Als je de definitie van d buiten de if zou plaatsen clutter je de omliggende scope alleen maar met onzinnige variabelen. Daarnaast heb je geen keuze als het runnen van de destructor van d (hier niet relevant omdat het een pointer betreft) essentieel is voor er verder gegaan wordt met de code na de if.

[ Voor 51% gewijzigd door .oisyn op 30-05-2006 16:59 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 11:55

hamsteg

Species 5618

Topicstarter
igmar schreef op dinsdag 30 mei 2006 @ 16:38:
[...]Totaal een non-argument als je het mij vraagt : een assignment levert altijd true op, en een beetje compiler geeft daar gewoon een warning op in combinatie met een if(). Verder is een enum gebruikt als boolean een cosmetisch iets : true is alles ongelijk aan 0.
Wat jij wil ... ik heb het niet verzonnen maar sta er wel achter. Als je bij gebrek aan een boolean type zelf een boolean creert moet je hem ook altijd als zodanig behandelen en niet stiekum toch als integer. Dit is gewoon een belangrijk gebrek geweest in de C standaard.

@.oisyn, grr je weet ook altijd de goede uitzondering te pakken :) Er zijn wel meer goede mogelijkheden, maar over het algemeen ....

[ Voor 10% gewijzigd door hamsteg op 30-05-2006 16:54 ]

Niet quoten, zorgvuldige reacties volgens de regels worden zo weggewerkt: *knip*, reactie op geknipte reactie.


  • Ivo
  • Registratie: Juni 2001
  • Laatst online: 14-01-2025

Ivo

Waarom zijn goto's achterhaald? Even een Delphi-voorbeeld analoog aan wat ik vandaag nodig had.
Delphi:
1
2
3
4
5
6
7
8
9
10
11
for i := 0 to List.Count - 1 do
begin
  if (P(List[i]) then
  begin
    val := i;
    goto out
  end
end;
Assert(False,'we didnt find an item in List satisfying P');
out:
//Do some other stuff


Dit is de reden waarom in Python de for-else constructie is ingevoerd.
Python:
1
2
3
4
5
6
for i in range(0,list.length):
  if p(list[i]):
    val = i
    break
else:
  Assert(false)

[ Voor 10% gewijzigd door Ivo op 30-05-2006 19:14 ]


  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 17-02 18:22
Ivo schreef op dinsdag 30 mei 2006 @ 19:12:
Waarom zijn goto's achterhaald? Even een Delphi-voorbeeld analoog aan wat ik vandaag nodig had.
Delphi:
1
2
3
4
5
6
7
8
9
10
11
for i := 0 to List.Count - 1 do
begin
  if (P(List[i]) then
  begin
    val := i;
    goto out
  end
end;
Assert(False,'we didnt find an item in List satisfying P');
out:
//Do some other stuff


Dit is de reden waarom in Python de for-else constructie is ingevoerd.
Python:
1
2
3
4
5
6
for i in range(0,list.length):
  if p(list[i]):
    val = i
    break
else:
  Assert(false)
Het probleem is dat je 'spaghetticode' krijgt als je niet oppast; je moet heel erg goed opletten waar je heen gaat bij bepaalde waardes, dus het wordt een soort van spoorzoeken. Dat is het nadeel. Ook ga ik er van uit dat de normale flow van je programma je 'alles gaat goed' scenario is. In dit geval zie ik een fout-assertion, die ik eigenlijk niet zou verwachten; alles ging toch goed? Dan lees ik nog eens terug en zie dat er gesprongen wordt naar buiten de loop. Maar zulke dingen kunnen ook een kwestie van gewenning zijn.

Hamsteggot:
Ik snap het, maar nog steeds snap ik niet waarom je de hele == true waarde erbij haalt. Bij een taal die booleans ondersteunt, en een functie die altijd een boolean returnt of een variabele die een boolean is, is het checken van de waarde in mijn ogen totale onzin en leidt het tot minder goed leesbare code. Voor C kan ik het nu begrijpen, maar dat is in mijn ogen een speciaal geval (dwz: geldt voor C, maar niet algemeen voor alle talen)

[ Voor 13% gewijzigd door Mithrandir op 30-05-2006 20:09 ]

Verbouwing

Pagina: 1 2 Laatste