Contract checking (Re: enforce()?)

Norbert Nemec Norbert at Nemec-online.de
Wed Jun 30 01:47:19 PDT 2010


On 28/06/10 12:59, bearophile wrote:
> Norbert Nemec:
>> [...] to place code for input contract checking in the *calling* code. [...]
>> Output contract checks, on the other hand should be compiled inside the
>> returning routine.
>
> Is this a positive thing to do? Can this be done? (D must support separate compilation, but in many situations this is not done/necessary, so maybe in such situations it can be done). Is Eiffel doing it? if it's a good thing and it's doable then what kind of changes does it require to the compiler?

These are good and pragmatic questions that you ask.

The whole issue only arises when doing separate compilation of a library 
and an application. (I use the term "application" for any code that uses 
the library.)

In an idea world (beware, I am switching of "pragmatic thinking mode" 
for a moment), I would describe the situation would as follows:

Either part can be compiled in "debug" mode or in "release" mode. Debug 
mode in the library means that you want to debug the library code 
itself. Release mode in the library means that you trust the library 
code to be correct and switch off all internal checks.

The interesting situation is when you compile the application in debug 
mode, using a stable library compiled in release mode. In this case, the 
input contracts of the library need to be checked to catch bugs in the 
application. Once the testing phase is finished, you want to compile the 
application and get rid of the contract checks.

In this idealized picture, the input contracts should clearly be checked 
in the application code so that the application developer has control 
over them.

Now, for the real world: Code is hardly never 100% bug free. I agree. 
With this argument, however, the concept of debug and release mode 
becomes pointless as you should never switch off the checks anyway. 
Assuming that you are not quite as paranoid you might still reach a 
point where you trust your code to switch off the checks. How about 
input contracts of a library?

As Simen mentioned in his post, there is the issue of library authors 
trying to avoid blame from application authors and the other way around. 
Ultimately, this is exactly what contracts are for: formalize the 
interface as much as possible and make it machine-checkable. If an 
application breaks, compile it in debug mode and see whether it finds 
the problem. With input contracts checked in the calling code, this 
would automatically switch on all the relevant checks to identify bugs 
in the application. If the application designer still tries to blame the 
library, why not simply supply a library compiled in debug mode? Any 
violation of a contract or an assertion unquestionably signals a bug in 
the code.

Can it be done? Certainly. The contract is part of the interface, so 
rather than compiling it into the DLL, it should be stored with the 
interface definitions and left for the application compiler to insert if 
requested. The code for this should not be any more involved than 
function inlining. Effectively, every function with contracts would be 
turned into a wrapper that first checks the contracts and then calls the 
real function in the DLL. The application compiler could then simply 
decide whether to inline the wrapper or simply call the function without 
checks.

I have no idea how Eiffel does it, but I am quite certain that this 
solution is following the original spirit of DbC of Bertrand Meyer.

Greetings,
Norbert


More information about the Digitalmars-d mailing list