| 
					
							
        
    
        
						
			 | 
			
			
					    
					
        
         
          
         
	
            | paranoia error check i alle funktioner Fra : Troels | 
  Dato :  06-04-05 08:31 |  
  |   
            
 Der er nogen der prøver at få trumfet et niveau af error check i ALLE 
 funktioner igennem, som jeg synes begynder at ligne paranoia.
 Jeg mener at have læst et par kommentarer her i gruppen med referencer til 
 en bog/webside der fremfører, at hvis dette gøres overdrevet og forkert, så 
 højner det faktisk ikke systemstabiliteten, mindsker ikke udviklingstiden, 
 etc - tvært imod.
 
 Erder nogen der kan hjælpe med et link ?
 
 tpt
 
 
 
  
            
             |   |   
            
        
 
            
         
           Niels Dybdahl (06-04-2005) 
         
	
            | Kommentar Fra : Niels Dybdahl | 
  Dato :  06-04-05 08:55 |  
  |   
            > Der er nogen der prøver at få trumfet et niveau af error check i ALLE
 > funktioner igennem, som jeg synes begynder at ligne paranoia.
 > Jeg mener at have læst et par kommentarer her i gruppen med referencer til
 > en bog/webside der fremfører, at hvis dette gøres overdrevet og forkert,
 så
 > højner det faktisk ikke systemstabiliteten, mindsker ikke udviklingstiden,
 > etc - tvært imod.
 
 Der er ingen tvivl om at hvis det gøres "forkert", så sænker det
 systemstabiliteten.
 Og det øger uden tvivl udviklingstiden.
 Det er også et helvede at teste al fejltestningskoden igennem.
 Defor bruger nyere sprog exceptions istedet. Det giver den hurtige
 udviklingstid, højere stabilitet (hvis man fanger disse exceptions på et
 passende sted) og meget nemmere test af fejlhåndtering.
 
 Så søg evt efter en begrundelse for hvorfor C++, C#, Java etc bruger
 exceptions.
 
 Niels Dybdahl
 
 
  
            
             |   |   
            
        
 
            
         
           Jesper Louis Anderse~ (06-04-2005) 
         
	
            | Kommentar Fra : Jesper Louis Anderse~ | 
  Dato :  06-04-05 11:12 |  
  |   
            Troels <nejtakjegf?rspamnok@dk.dk> wrote:
 
 > Der er nogen der pr?ver at f? trumfet et niveau af error check i ALLE 
 > funktioner igennem, som jeg synes begynder at ligne paranoia.
 > Jeg mener at have l?st et par kommentarer her i gruppen med referencer til 
 > en bog/webside der fremf?rer, at hvis dette g?res overdrevet og forkert, s? 
 > h?jner det faktisk ikke systemstabiliteten, mindsker ikke udviklingstiden, 
 > etc - tv?rt imod.
 
 Det er ikke helt klart hvad du mener med error check. Mener du noget i stil
 med
 
 foobar (baz *p)
 {
    assert(p != NULL);
 
    ...
 }
 
 Eller, mener du det, som Niels Dybdal siger (at man checker returvaerdi
 for et systemkald). Det sidste er paa nogen maader et problem, men med 
 passende abstraktionsbibliotek er det faktisk til at komme uden om. Det 
 tager dog lang tid at skrive et saadant. Jeg foretraekker som regel 
 exception-baserede mekanismer, der _ikke_ bare er bygget paa setjmp(). Det
 har jeg set for mange gange nu, til jeg synes det er sjov.
 
 Du kunne ogsaa mene unit-tests. Det tror jeg generelt ikke saenker laesbarheden
 og stabiliteten af koden.
 
 Kort sagt, hvad mener du?
 
 
 -- 
 jlouis
  
            
             |   |   
            
        
 
            
         
           Troels (06-04-2005) 
         
	
            | Kommentar Fra : Troels | 
  Dato :  06-04-05 15:27 |  
  |   
            
 Generelt:
 Jeg mener at en funktion / modul bør lave checks på de ting den har ansvar 
 for. Om det giver mening på et højere niveau, har det ovenliggende niveau 
 ansvar for, og så må det checkes her.
 
 Hvis jeg har en driverfunktion der har til opgave at tænde noget lys, er jeg 
 imod at indføre noget kode i driveren der checker om system staten er som 
 den skal være. Hvis nogen kalder lightOn() ja så tændes lyset.
 
 Derudover så irriterer den sidste else i dette mig :
 
 typedef enum
 {
   FALSE,
   TRUE
 }BOOL;
 
 BOOL testSomething ()
 {
   if ( ....)
     return TRUE;
   else
     return FALSE
 }
 
 void myFunc()
 {
   if ( testSomething () == TRUE )
   {
     .........
   }
   else if ( testSomething () == FALSE )
   {
     ......
   }
   else
   {
     // panic !!
   }
 }
 
 En anden udgave af det samme:  Switch som en luxus if er forbudt :
 switch (state)
 {
   case ON:
   case PAUSE:
     doSomething
 }
 
 skal laves således at ALLE enum værdier nævnes:
 switch (state)
 {
   case ON
   case PAUSE
     doSomething()
     break;
   case OFF
     // do nothing
     break;
 default:
   doPanic(); // unknown state
   break;
 }
 
 Her er jeg måske bare sart?
 
 tpt
 
 "Jesper Louis Andersen" <jlouis@miracle.mongers.org> skrev i en meddelelse 
 news:n8pci2-9t4.ln1@miracle.mongers.org...
 > Troels <nejtakjegf?rspamnok@dk.dk> wrote:
 >
 >> Der er nogen der pr?ver at f? trumfet et niveau af error check i ALLE
 >> funktioner igennem, som jeg synes begynder at ligne paranoia.
 >> Jeg mener at have l?st et par kommentarer her i gruppen med referencer 
 >> til
 >> en bog/webside der fremf?rer, at hvis dette g?res overdrevet og forkert, 
 >> s?
 >> h?jner det faktisk ikke systemstabiliteten, mindsker ikke 
 >> udviklingstiden,
 >> etc - tv?rt imod.
 >
 > Det er ikke helt klart hvad du mener med error check. Mener du noget i 
 > stil
 > med
 >
 > foobar (baz *p)
 > {
 > assert(p != NULL);
 >
 > ...
 > }
 >
 > Eller, mener du det, som Niels Dybdal siger (at man checker returvaerdi
 > for et systemkald). Det sidste er paa nogen maader et problem, men med
 > passende abstraktionsbibliotek er det faktisk til at komme uden om. Det
 > tager dog lang tid at skrive et saadant. Jeg foretraekker som regel
 > exception-baserede mekanismer, der _ikke_ bare er bygget paa setjmp(). Det
 > har jeg set for mange gange nu, til jeg synes det er sjov.
 >
 > Du kunne ogsaa mene unit-tests. Det tror jeg generelt ikke saenker 
 > laesbarheden
 > og stabiliteten af koden.
 >
 > Kort sagt, hvad mener du?
 >
 >
 > -- 
 > jlouis 
 
 
  
            
             |   |   
            
        
 
            
         
            Morten Guldager (06-04-2005) 
         
	
            | Kommentar Fra : Morten Guldager | 
  Dato :  06-04-05 17:48 |  
  |  
 
            2005-04-06 Troels wrote
 >
 > Generelt:
 > Jeg mener at en funktion / modul bør lave checks på de ting den har ansvar 
 > for. Om det giver mening på et højere niveau, har det ovenliggende niveau 
 > ansvar for, og så må det checkes her.
 >
 > Hvis jeg har en driverfunktion der har til opgave at tænde noget lys, er jeg 
 > imod at indføre noget kode i driveren der checker om system staten er som 
 > den skal være. Hvis nogen kalder lightOn() ja så tændes lyset.
 >
 > Derudover så irriterer den sidste else i dette mig :
 > ...
 > default:
 >   doPanic(); // unknown state
 >   break;
 > }
 >
 > Her er jeg måske bare sart?
 Det synes jeg. Det er meget almindeligt at nogen får introduceret en
 ny funktionalitet i en andens kode, helt uden at fortælle om det.
 Den slags kan man fange med sådan en "internal program error" ting.
 Jeg bruger ihvertfald den slags "dette er en umulig situation" checks
 i mine statemaskiner. (som dog er skrevet i perl)
 /Morten   
            
             |   |   
            
        
 
            
         
            Jesper Louis Anderse~ (06-04-2005) 
         
	
            | Kommentar Fra : Jesper Louis Anderse~ | 
  Dato :  06-04-05 19:00 |  
  |   
            Troels <nejtakjegf?rspamnok@dk.dk> wrote:
 
 > Her er jeg m?ske bare sart?
 
 Nej, du har bare valgt det forkerte sprog at programmere i. Du er noedt til at
 lave en del safeguarding, fordi det som regel fjerner fejl af den mere lumske
 type. Jeg synes ikke at defensiv programmering er en daarlig ting. Tvaertimod.
 
 
 -- 
 jlouis
  
            
             |   |   
            
        
 
            
         
            Niels Dybdahl (07-04-2005) 
         
	
            | Kommentar Fra : Niels Dybdahl | 
  Dato :  07-04-05 08:41 |  
  |   
            > Derudover så irriterer den sidste else i dette mig :
 >
 > typedef enum
 > {
 >   FALSE,
 >   TRUE
 > }BOOL;
 >
 > BOOL testSomething ()
 > {
 >   if ( ....)
 >     return TRUE;
 >   else
 >     return FALSE
 > }
 >
 > void myFunc()
 > {
 >   if ( testSomething () == TRUE )
 >   {
 >     .........
 >   }
 >   else if ( testSomething () == FALSE )
 >   {
 >     ......
 >   }
 >   else
 >   {
 >     // panic !!
 >   }
 > }
 
 Hvis det er et multitrådet program, så kan testSomething returnere noget
 andet i andet kald end første også giver det mening. Hvis det ikke er
 multitrådet så er der ikke så meget mening i at kalde testSomething to gange
 og så falder det sidste else væk.
 
 > En anden udgave af det samme:  Switch som en luxus if er forbudt :
 > switch (state)
 > {
 >   case ON:
 >   case PAUSE:
 >     doSomething
 > }
 >
 > skal laves således at ALLE enum værdier nævnes:
 > switch (state)
 > {
 >   case ON
 >   case PAUSE
 >     doSomething()
 >     break;
 >   case OFF
 >     // do nothing
 >     break;
 > default:
 >   doPanic(); // unknown state
 >   break;
 > }
 
 Det er en god vane altid at inkludere default. Derved tvinges man til at
 overveje hvad der skal ske ved andre værdier. Ofte kan man bare sætte en
 kommentar og en break ind, så andre kan læse at situationen er blevet
 overvejet.
 
 Niels Dybdahl
 
 
  
            
             |   |   
            
        
 
            
         
             Troels (08-04-2005) 
         
	
            | Kommentar Fra : Troels | 
  Dato :  08-04-05 11:16 |  
  |   
            >
 > Hvis det er et multitrådet program, så kan testSomething returnere noget
 > andet i andet kald end første også giver det mening. Hvis det ikke er
 > multitrådet så er der ikke så meget mening i at kalde testSomething to 
 > gange
 > og så falder det sidste else væk.
 >
 
 Ja, to kald af funktionen er fjollet, men det bagvedliggende princip om 
 "check af hele værdimængden" hvor jeg skal checke om min BOOL enum er 
 _andet_ end TRUE eller FALSE holder jo stadig. Og det hader jeg.
 
 Iøvrigt står der heldigvis "bør" mange steder i en sådan kodestandard, så 
 lidt plads er der vel til sund fornuft. Det kunne jo være at man fik en 
 konsensus om at det er ok at nøjes med at checke TRUE/FALSE på lige netop 
 BOOL typen.
 
 tpt
 
 
 
  
            
             |   |   
            
        
 
            
         
           Mogens Hansen (07-04-2005) 
         
	
            | Kommentar Fra : Mogens Hansen | 
  Dato :  07-04-05 18:35 |  
  |   
            
 "Troels" <nejtakjegfårspamnok@dk.dk> wrote in message 
 news:4253902b$0$243$edfadb0f@dread11.news.tele.dk...
 >
 > Der er nogen der prøver at få trumfet et niveau af error check i ALLE 
 > funktioner igennem, som jeg synes begynder at ligne paranoia.
 
 Meget generelle regler, der siger at ALLE funktioner skal et eller andet vil 
 være vanskelige at gennemføre, idet verden ikke er tilstrækkelig homogen.
 Reglerne skal være lidt mere afslappet for at være troværdige.
 
 Når det er sagt er det en vældig god ide at overveje hvad der er pre- og 
 post-condition for at kalde en funktion.
 Altså hvilke betingelser skal være opfyldt for at man må kalde funktionen, 
 og hvilke betingelser er garanteret at gælde når funktionen har returneret.
 Man kan sikkert finde noget nyttigt om emnet ved f.eks. at kigge på nogen af 
 de overvejelser som Betrand Meyer har i gjort i forbindelse med design by 
 contract.
 
 I C og C++ kan man udtrykke pre- og post-conditions ved at anvende assert.
 På den måde bliver det både dokumenteret overfor andre programmører og det 
 bliver løbende verificeret under udvikling at det bliver overholdt.
 
 Et godt eksempel jeg lige faldt over stammer fra "C/C++ Users Journal", 
 april 2005 side 51:
 
 vector<int>::size_type firstprod(const vector<int>& v, int n)
 {
    assert(!v.empty());
    for(vector<int>::const_iterator it = v.begin(); it != v.end(); ++it)    {
       int val = *it * n;
       if(val > v.back())
          return val;
    }
    assert(false);
 }
 
 Den første assert siger at det er en pre-condition at "v" ikke er tom.
 Den anden assert siger at det er en post-condition at det var muligt at 
 finde et gyldigt svar.
 
 Man kunne have valgt andre løsninger:
    * Putte noget i vectoren hvis den er tom
    * Kaste en exception hvis den er tom
 men den form for defensiv programmering, vil kunne dække over en 
 misforståelse hos programmøren der kalder funktionen.
 
 Generelt syntes jeg at det er bedre at et program går ned med et højt brag 
 end at det forsøger at fortsætte på ukendte forudsætninger.
 
 > Jeg mener at have læst et par kommentarer her i gruppen med referencer til 
 > en bog/webside der fremfører, at hvis dette gøres overdrevet og forkert, 
 > så højner det faktisk ikke systemstabiliteten, mindsker ikke 
 > udviklingstiden, etc - tvært imod.
 
 Jeg mener at overvejelser og klarhed omkring pre- og post-condition kan 
 bidrage væsentligt til at øge system stabilitet, mindske udviklingstid og 
 lette vedligehold.
 
 Venlig hilsen
 
 Mogens Hansen 
 
 
  
            
             |   |   
            
        
 
            
         
           Troels (08-04-2005) 
         
	
            | Kommentar Fra : Troels | 
  Dato :  08-04-05 11:07 |  
  |   
            >
 > vector<int>::size_type firstprod(const vector<int>& v, int n)
 > {
 >   assert(!v.empty());
 >   for(vector<int>::const_iterator it = v.begin(); it != v.end(); ++it) 
 > {
 >      int val = *it * n;
 >      if(val > v.back())
 >         return val;
 >   }
 >   assert(false);
 > }
 >
 > Den første assert siger at det er en pre-condition at "v" ikke er tom.
 > Den anden assert siger at det er en post-condition at det var muligt at 
 > finde et gyldigt svar.
 >
 
 Ja, den checker på alle de ting den har at operere på. Fint.
 
 En anden ting er så at funktionen vil blive fanget af (forslag til) vores 
 kodestandard på to andre punkter, nemlig.
 * multible exit-points
 * for løkker skal altid køres helt igennem, ellers bruges top / bundtest 
 konstruktionerne while eller do-while
 
 Hvad synes folk om disse to regler ?
 ( personligt holder jeg meget af at breake mig ud af for sætninger , men 
 .... )
 
 tpt
 
 
  
            
             |   |   
            
        
 
            
         
            Morten Guldager (08-04-2005) 
         
	
            | Kommentar Fra : Morten Guldager | 
  Dato :  08-04-05 13:52 |  
  |  
 
            2005-04-08 Troels wrote
 >>
 >> vector<int>::size_type firstprod(const vector<int>& v, int n)
 >> {
 >>   assert(!v.empty());
 >>   for(vector<int>::const_iterator it = v.begin(); it != v.end(); ++it) 
 >>   {
 >>      int val = *it * n;
 >>      if(val > v.back())
 >>         return val;
 >>   }
 >>   assert(false);
 >> }
 >
 > En anden ting er så at funktionen vil blive fanget af (forslag til) vores 
 > kodestandard på to andre punkter, nemlig.
 > * multible exit-points
 > * for løkker skal altid køres helt igennem, ellers bruges top / bundtest 
 > konstruktionerne while eller do-while
 >
 > Hvad synes folk om disse to regler ?
 Trælse.
 > ( personligt holder jeg meget af at breake mig ud af for sætninger 
 Det er ihvertfald også en teknik jeg bruger ofte.
 Men det kræver at man så har styr på e.v.t. oprydning andetsteds.
 /Morten   
            
             |   |   
            
        
 
            
         
            Niels Dybdahl (08-04-2005) 
         
	
            | Kommentar Fra : Niels Dybdahl | 
  Dato :  08-04-05 14:35 |  
  |   
            > > vector<int>::size_type firstprod(const vector<int>& v, int n)
 > > {
 > >   assert(!v.empty());
 > >   for(vector<int>::const_iterator it = v.begin(); it != v.end(); ++it)
 > > {
 > >      int val = *it * n;
 > >      if(val > v.back())
 > >         return val;
 > >   }
 > >   assert(false);
 > > }
 > >
 > > Den første assert siger at det er en pre-condition at "v" ikke er tom.
 > > Den anden assert siger at det er en post-condition at det var muligt at
 > > finde et gyldigt svar.
 > >
 >
 > Ja, den checker på alle de ting den har at operere på. Fint.
 >
 > En anden ting er så at funktionen vil blive fanget af (forslag til) vores
 > kodestandard på to andre punkter, nemlig.
 > * multible exit-points
 > * for løkker skal altid køres helt igennem, ellers bruges top / bundtest
 > konstruktionerne while eller do-while
 > Hvad synes folk om disse to regler ?
 
 Som nævnt bruger jeg exceptions til fejlhåndtering, hvilket gør at der er
 mange exitpoints i mine programmer.
 Løkker bliver uoverskuelige, hvis man skal plastre dem til med boolske
 variable, som holder styr på om man skal hoppe ud ved slutningen eller ej.
 Så foretrækker jeg en pænere struktur som for det meste afspejler problemet
 bedre.
 Da jeg læste på DTH blev vi også frarådet at opbygge "tilstandsmaskiner"
 hvor det ikke er nødvendigt.
 
 Niels Dybdahl
 
 
  
            
             |   |   
            
        
 
            
         
            Mogens Hansen (08-04-2005) 
         
	
            | Kommentar Fra : Mogens Hansen | 
  Dato :  08-04-05 18:36 |  
  |   
            
 "Troels" <nejtakjegfårspamnok@dk.dk> wrote in message 
 news:425657db$0$276$edfadb0f@dread11.news.tele.dk...
 > >
 >> vector<int>::size_type firstprod(const vector<int>& v, int n)
 >> {
 >>   assert(!v.empty());
 >>   for(vector<int>::const_iterator it = v.begin(); it != v.end(); ++it) {
 >>      int val = *it * n;
 >>      if(val > v.back())
 >>         return val;
 >>   }
 >>   assert(false);
 >> }
 >>
 >> Den første assert siger at det er en pre-condition at "v" ikke er tom.
 >> Den anden assert siger at det er en post-condition at det var muligt at 
 >> finde et gyldigt svar.
 >>
 >
 > Ja, den checker på alle de ting den har at operere på. Fint.
 >
 > En anden ting er så at funktionen vil blive fanget af (forslag til) vores 
 > kodestandard på to andre punkter, nemlig.
 > * multible exit-points
 
 Det kan være meget nyttigt at returnere fra flere steder i en funktion.
 Det kan sagtens gøre strukturen mere klar. Ikke mindst hvis man anvender det 
 med RAII.
 
 > * for løkker skal altid køres helt igennem, ellers bruges top / bundtest 
 > konstruktionerne while eller do-while
 
 Se ovenstående funktion - der er vist ikke noget objektivt at udsætte på 
 den.
 
 >
 > Hvad synes folk om disse to regler ?
 
 Meget firkantede regler er sjældent fornuftige.
 Uddannelse der belyser baggrunder for hvorfor nogle foreslår en given regel 
 er langt mere nyttig.
 
 Venlig hilsen
 
 Mogens Hansen 
 
 
  
            
             |   |   
            
        
 
            
         
            Jesper Dybdal (08-04-2005) 
         
	
            | Kommentar Fra : Jesper Dybdal | 
  Dato :  08-04-05 19:00 |  
  |  
 
            "Troels" <nejtakjegfårspamnok@dk.dk> wrote:
 >En anden ting er så at funktionen vil blive fanget af (forslag til) vores 
 >kodestandard på to andre punkter, nemlig.
 >* multible exit-points
 >* for løkker skal altid køres helt igennem, ellers bruges top / bundtest 
 >konstruktionerne while eller do-while
 >
 >Hvad synes folk om disse to regler ?
 De er absurde.  Så skal man jo til at simulere de to konstruktioner vha.
 booleans, og det gør da koden helt ulæselig - og forøger risikoen for fejl
 betragteligt.
 Hvis jeg har forstået dig ret, så skal I fx omskrive den helt normale og
 perfekt læselige konstruktion:
    for (;;)
    {   <kodestump A>
       if (<betingelse>)
          break;
       <kodestump B>
    }
 til enten noget med kodegentagelse:
    <kodestump A>
    while (!<betingelse>)
    {   <kodestump B>
       <kodestump A>
    }
 eller noget med at bruge en boolean til at implementere break:
    Done = FALSE;
    while (!Done)
    {   <kodestump A>
       if (<betingelse>)
          Done = TRUE;
           else
          <kodestump B>
    }
 Begge dele er umådelig kluntede i forhold til den naturlige med break - og man
 kan alligevel først gennemskue logikken når man har indset at det bare er en
 løkke med exitbetingelsen i midten, skrevet på ulæseligt Pascal'sk i stedet
 for med C's naturlige "break".  Det samme gælder multiple "return"s.
 Hvis din arbejdsplads vil have Pascal-kode, hvorfor så bruge en C-oversætter
 til det?
 Paranoide fejltjek har jeg derimod meget sympati for - hvis det ikke
 overdrives.
 -- 
 Jesper Dybdal, Denmark.
 http://www.dybdal.dk (in Danish).
            
              |   |   
            
        
 
    
 
					
					 
			 | 
			
				
        
			 |