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