Writing Bug-Free C/D Code

Derek Parnell derek at psych.ward
Thu Mar 22 09:58:38 PDT 2007


On Thu, 22 Mar 2007 09:20:01 -0700, Sean Kelly wrote:

> Derek Parnell wrote:

>>>   Should we just ignore the 'in' clause altogether then?  
>> 
>> No, of course not. But using the current D implementation, one should not
>> rely on it for production editions of your application. Use it only for
>> development editions. Then, armed with this implementation of precondition
>> contracts, one should use them to validate the logic of your algorithms and
>> not the validity of incoming data.
> 
> But this suggests that I should either do parameter checking both in the 
> 'in' clause and in the function body using separate implementations 
> (since assert is not an option).  This complicates maintenance, hurts 
> readability, and reduces the overall utility of the contract programming 
> features IMO.

Huh? Why would you do it twice? That's crazy talk. Just code the validation
once; at the start of the 'body' block. The effect is identical to coding
it in the 'in' block only *and* not compiling with -release. No need to
code the validation twice at all.

  int doubleit(int x, int y)
  body
  {
      // validate params.
      {
           if (y < 0) y = -y;
           if ((x < -y) || (x > y))
           {
               throw new Exception(ReportErr( RangeErr, x, -y, y));
           }
      }

      // Do the work now everything's okay.
      return x + x;
  }
  out(res)
  {
     assert(res = x*2, format("doubleit(%d): Weird Math Error", x));
  }
  unittest
  {
     assert( doubleit(-10) == -20 );
     assert( doubleit( -1) ==  -2 );
     assert( doubleit(  0) ==   0 );
     assert( doubleit(  1) ==   2 );
     assert( doubleit( 10) ==  20 );
     try{    doubleit(-111); } catch(Exception e) { writefln("%s", e.msg);}
     try{    doubleit(-11);  } catch(Exception e) { writefln("%s", e.msg);}
     try{    doubleit( 11);  } catch(Exception e) { writefln("%s", e.msg);}
     try{    doubleit( 111); } catch(Exception e) { writefln("%s", e.msg);}
  }
               
With this setup, I don't have to be concerned that -release will ignore my
out block as the function inputs are still validated.

> By the way, can someone tell me what is 
> included when both -debug and -release are set?

-debug compiles *in* anything that is inside a debug block.
  e.g.  debug { writefln("Got here"); }
It has nothing whatsoever to do with -release or -unittest. It is
functionally identical to -version except that it allows 'anonymous'
blocks.

-release does not compile in asserts, 'in' blocks, or 'out' blocks. 


-- 
Derek Parnell
Melbourne, Australia
"Justice for David Hicks!"
skype: derek.j.parnell



More information about the Digitalmars-d mailing list