Writing Bug-Free C/D Code

Derek Parnell derek at nomail.afraid.org
Thu Mar 22 19:22:06 PDT 2007


On Thu, 22 Mar 2007 14:54:20 -0400, Dan wrote:

> Derek Parnell Wrote:
> 
> IMHO: Yuck.

I just knew that if I didn't write an off-the-cuff example that wasn't 110%
perfect I'd have some people pooh-poohing the concept I was trying to get
across. Sheesh - it was 3:58AM when I wrote that after having been up since
6:30AM the previous day!
 
> Here's what I think *ought* to be done to solve the problem of
> guaranteeing that code is error free for input ranges;

That was not the point of the example! 

The point was, using current D, the 'in' block can never be guaranteed to
be executed so don't rely on using the 'in' block for parameter validation
- whatever that validation happens to be.
 
> int doubleit(int x, int y)
> in {
>   // note: you say if y is negative, make it positive twice and test <-y?
>   // you then tested the original proposition ALSO!

Get a grip, eh? It was a silly example and didn't mean to represent best
practice. The actual code used is totally irrelevant to my argument.

>   assert(x > y);
> }

Now, if this is compiled using '-release' then your precious assert test is
quietly ignored and the user gets a nasty run time error, as opposed to a
nice run time error.

> body {
>   return x+x;
> }
> out(result) {
>   assert( result == x*2, format("doubleit(%d): Weird Math Error", x) );
> }
> 
> What should then happen is this:  The compiler should recognize that
> we only accept values such that x > y.  Knowing that, it should then
> verify that in all cases where this function can be called, that the
> input to the function must have this condition.  In cases where this
> *can* fail, it should raise an error - such as variables that are
> affected by user input or outside parameters that aren't already
> bounds checked or adjusted...

If I was to ask for an improvement in the compiler, with respect to
assert() and in{}, it would be to enable us to target exactly which parts
of the DbC to excluded in a build. Personally, if I could, I'd never
exclude in{} or out{} blocks with the -release switch. Instead I'd like to
code them more like ...

  int somefunc( ... )
  in { ...validate inputs ...}
  body { ... }
  debug(logic) out {}

and then when developing I'd compile with -debug=logic and when compiling
the production edition I'd just leave out the -debug switch but use
-release to skip over assert().
 


-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Justice for David Hicks!"
23/03/2007 1:02:58 PM



More information about the Digitalmars-d mailing list