templatizing parameters and induction (was Re: Writing Bug-Free

Dan murpsoft at hotmail.com
Fri Mar 23 11:26:07 PDT 2007


> >>> Andrei Alexandrescu (See Website For Email) wrote:
> >>>> [...]
> >>>> int foo(int x, int y, int z);
> >>>> int foo(static int x, int y, int z); // x is known during compilation
> >>>> int foo(int x, static int y, int z); // y is known during compilation
> >>>> int foo(static int x, static int y, int z); // x and y are... you know
> >>>> [...]
> >>>> final a = to!(int)(readln), b = to!(int)(readln);
> >>>> foo(a, b, b);  // firsts overload
> >>>> foo(1, a + b, b); // 2nd
> >>>> foo(a + b, a - b, b);  // 3rd
> >>>> foo(42, 7, b); // 4th
> >>>> [...]
> >>>
> >>> Great sir, could you impart upon us mere mortals the wisdom by which 
> >>> you are able to ascertain, at compile time, the difference between 
> >>> two values known only at runtime (a la the "3rd" overload)?  We are 
> >>> in great need of such Oracle-like behavior.
> >>
> >> I also notice you're still posting from the future. You must make good 
> >> money daytrading. Future postulae commotus est. :o)

Dear sirs, I have such wisdom.  

Your example is absolutely packed with bugs.  First, you are reading an entire line into an int.  May I pass the pi?

I can tell you that the range of a uint is 0..4294967295.  
I also say with cofidence that int is -2147483648..2147483647.  Knowing that, good sirs, you are most likely unwittingly causing a bug by calling foo(a+b) where a and b are ints.

I say most likely because you may intend for the program to overflow if(a+b > int.max)

I can also say that if you add any two unbound integers and attempt to store them in another integer, you are likewise creating an opportunity for a bug.

So... let's bound them shall we?

void moveTo(Item it, int x, int y)
in {
   assert(x > 0);
   assert(y > 0 && y < SCREEN.MAXHEIGHT);
}
body {
  it.left = x;
  it.top = y;
}

... elsewhere...

void setLayout(int a, ubyte b)
{
   moveTo(a-350,b);
}

We now know that in this case, a had better be >= 350, or our assert ought to fail.  In fact, it's a bug, because it *could* be < 350.  We also know the upper bound is no longer 2147483647, but 2147483297 for x.

For y, we know that the possible bounds are in fact only 0-255, while the function will accept anything between 0 and SCREEN.MAXHEIGHT, whatever arbitrary number that ought to be.

So we do know something about it, and we can proveably demonstrate that the program will work for all cases, or it won't with variables being used.

Welcome to discrete mathematics 101.
   



More information about the Digitalmars-d mailing list