Contract checking (Re: enforce()?)
Norbert Nemec
Norbert at Nemec-online.de
Wed Jun 30 12:03:07 PDT 2010
On 30/06/10 17:45, Sean Kelly wrote:
> Norbert Nemec Wrote:
>
>> 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.
>
> I see the choice of "release" for disabling contracts as a huge mistake in nomenclature. For libraries, I would ship a checked and unchecked build (with -release disabled and enabled), but none with -debug or -unittest set. Those are for internal testing and the user shouldn't care to turn on debug code in a library simply because he's debugging his own app.
>
> The idea of compiling the "in" contract into the application code is an interesting one, but I suspect it could be tricky. Consider an unchecked build of the library, a checked build of the app, and now taking the address of a library function. Worse, what if a library routine returns the address of another library routine? Now the application has a reference to an unchecked version of the function, even if the involved technical hurdles are surmounted (multiple entry points or the like).
That's indeed an interesting aspect: Design by Contract (DbC) and
function pointers. I am not sure how these concepts would merge properly
at all.
The contracts are part of the interface, so they should in fact be part
of the function pointer type! Of course this would quickly become
ridiculous.
A strongly object oriented language like Eiffel can in principle do
without function pointers. Instead, one can in most cases use classes
with virtual functions that offer very similar functionality. A class
interface comes with all the contracts, so everything is safe and sound.
I really do not know how to deal with function pointers in the clean DbC
paradigm. If you assign a function with input contracts to a function
pointer, whoever uses the pointer does not know about the contracts.
This however, breaks down the strong DbC concept and turns contracts
into mere run time checks.
Does this mean that D should give up the goal of proper DbC? Simply do
the pragmatic thing and pick the best pieces from DbC without worrying
about formal completeness? I guess so...
More information about the Digitalmars-d
mailing list