www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - More thoughts on compile-time contracts

reply Daniel Horn <hellcatv hotmail.com> writes:
Let me preface this message by saying that the code analysis work done 
by the compiler and less by the runtime, the shorter the development cycle.

I think languages need radical new features to support better 
compile-time analysis of programs.

Walter and D designers have had great ideas wrt contracts, but contracts 
are too late for preventing the problem at compile time.
THe same holds for uninitialized values--setting them to NaN is great at 
run time, but what about compile time.

C++ has this const notion--which is a step in the right direction, but 
it mucks up the typing interface and makes the programmer do unnecessary 
work.
"If C++ can tell me that it's const why do I need to write it!"-- good 
point.

instead we need a more powerful method of expressing const and other 
compile time invariants that have our compiler doing the work to check 
our sloppy code.

for instance...const does NOT solve div/0 problems that could arise.
const does NOT solve sqrt(-1) problems that could arise.

but the compiler can often tell that I'm never going to have a divide by 
zero.

Let us start with making a better contract that supercedes const, since 
the behavior is a lot easier and more straightforward than asserting 
math-ops to be true (oh but what if he does an if(0) around it... blah).

So I'm back to my const_assert idea:
my_class x = new my_class;
const_assert(x.mymember) {
    x.memberfunc();//only asserts if that changes the mymember var
    x.mymember=0;//fails, even if mymember was an int that the compiler 
"knows" is zero (unassigned for instance)
}

so what if you take this to globals:

my_class x = new my_class;
const_assert(x) {
   my_class *[10]y;
...
   y[5]=x;
// so far so good nothing refers to y.
   my_global = y;// global var gets y...  the compiler could either punt 
here and say "uh oh, global got a pointer to my value, compile fail!" or 
it could  put an internal const flag on that array and recheck the 
entire code to assure that nothing assigned to the value stored in that 
array. (if it was linked to externally, however it would have to punt 
because another lib could access the pointer)
}

the long and short of it is that this sort of compile time analysis 
could be done by propogating const to the far corners of the library 
being compiled (those closed source libs not being compiled would have 
to be trusted to have the right const_asserts around their definitions, 
or else print warnings to the output)

does anyone think this is a useful idea?
it must not stay at the const level, but I think similar ideas could be 
used to help me check that I'm never using a NaN for instance, or that 
my variables are always assigned to.
Or that a particular value is never assigned to between the beginning 
and end of a function call. (same as a contract, but static-compile time)

the language standard would have to set exactly how these assertions 
worked--i.e. that they traversed ALL code paths, even improbable ones 
(i.e. if (0) ) so that each compiler would assert at the same time.

--Daniel
Apr 29 2004
parent "Walter" <newshound digitalmars.com> writes:
I think you are on the right track. Much of what you are thinking about can
be done with global data flow analysis across the entire program.
May 11 2004